JavaScript:将函数分配为回调函数和变量作用域

3

那么,这就是问题所在。我使用onclick事件来触发函数,因此每次单击时,您将在div的原始innerHTML和另一个变量之间切换。当我将testfunction指定为回调时,它可以工作。以下是代码:

var c = '';

function testfunction()
{
    var a = this.innerHTML;

    var b = 'blah';

    if (a !== b)
    {
        c = a;
        return this.innerHTML = b;
    }
    else
    {
        return this.innerHTML = c;
    }

    window.onload = function()
    {
         document.getElementById('rightcontent').onclick = testfunction;
    }

我理解c因为它的全局作用域而保留了它的值。但我不明白的是,当我将函数放入匿名回调中时,为什么c会返回undefined,如下所示:

    windows.onload = function()
    {
    document.getElementById('rightcontent').onclick = function()
    {
         this.innerHTML = testfunction();
    }
    }

这些都是没有实际意义的,我只是在胡闹……但我想知道底层发生了什么。

如果这已经在其他地方有涉及,请原谅我,我已经查看了一些帖子,但是找不到答案。

提前感谢 :-)


搜索[javascript] this作用域或类似内容。 - user166390
你是不是想在 testfunction 函数内设置 window.onload - Justin Morgan
@JustinMorgan:不,但我不知道为什么我应该或不应该。另外,我已经更正了testfunction(),现在返回正确。 - whosmav
window.onload会在文档加载完成后运行。因此,如果您在该事件之后的任何时间调用testfunction,设置window.onload将不起作用。我不知道您想做什么,虽然在DOM加载之前运行代码是可能的,但这并不是最常见的事情。 - Justin Morgan
2个回答

2
我理解,c 由于其全局作用域而保留了其值。但我不明白的是,当我将该函数放入匿名回调中时,为什么 c 返回未定义,例如:

在您的第二个片段中,this 不等于 #rightcontent,而等于 window。因此,window.innerHTML 是未定义的,因此在您的 if/else 块中采取了第一个分支。

c 被赋值为 undefined,并且返回 undefined

您可以使用 callapply 调用方法并指定特定上下文:

document.getElementById('rightcontent').onclick = function () {
    this.innerHTML = testfunction.call(this);
}

例子:http://jsfiddle.net/dySA5/ 你的第一个代码片段之所以没有表现出这种行为,是因为当调用该方法时,浏览器将this设置为被点击的元素。

非常感谢!我已经修正了testfunction()的返回值。还有一些事情:在testfunction()的返回部分中,“this”是否也指窗口?或者被调用后是否已经移动到div中?另外,有趣的是,当使用匿名回调方式时,你可以直接返回变量,而不是使用“this.innerHTML = var”。为什么会这样?此外,对于匿名回调,你既可以使用“return this.innerHTML = var”,也可以只使用“return = var”,并且它们给出相同的结果…… 难道这就是这样吗? - whosmav
此外,当将testfunction()分配给onclick时,我必须使用return this.innerHTML = var。 - whosmav
2
@whosmav: 当使用匿名回调方式时,你可以直接返回变量,而不是this.innerHTML = var。为什么?:因为你正在匿名回调内部分配返回值:this.innerHTML = testfunction.call(this);。这并没有什么神奇的地方,只是在不同的行上分配了值。另外,FYI:http://www.quirksmode.org/js/this.html。 - Felix Kling

1

http://jsfiddle.net/2aDJS/4/

我清理并使用jQuery改进了你的示例,使其更易于阅读:

var c = '';

function testfunction() {
  console.log(this)
  var a = this.innerHTML;

  var b = 'blah';

  if (a !== b) {
    c = a;
    this.innerHTML = b;
  } else {
    this.innerHTML = c;
  }
}

$(document).ready(function () {
  $('#rightcontent').click(function () {
    testfunction.call(this);
    //testfunction();
  });

  //$('#rightcontent').click(testfunction);
})

你看到函数调用被包裹在一个失败的函数中的原因是因为这样做会改变作用域。在事件处理程序中,this被解释为事件引发元素。如果你在事件处理程序中调用一个函数并希望它引用自己,除非你使用function.call(scope)明确调用作用域,否则它的this将不会被改变。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接