javascript:将函数指定为回调和变量作用域

时间:2013-01-08 23:14:42

标签: javascript

所以,这是交易。我正在使用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();
    }
    }

没有任何意义,我只是搞乱......但我想知道引擎盖下发生了什么。

很抱歉,如果在其他地方有这个问题,我已经查看了一些帖子以找到我的答案,但我找不到它。

提前致谢: - )

2 个答案:

答案 0 :(得分:2)

  

据我所知,c因其全球范围而保留了它的价值。但我不明白的是,当我将函数放入匿名回调时,为什么c返回undefined:

在您的第二个代码段中,this不等于#rightcontent,它等于windowwindow.innerHTML未定义,因此第一个分支将在if/else块中进行。

c被分配undefined,并返回undefined

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

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

示例: http://jsfiddle.net/dySA5/

您的第一个代码段没有出现此行为的原因是因为浏览器在调用方法时将this设置为被点击的元素。

答案 1 :(得分:1)

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

我清理了并且jQuerified你的例子让它更容易阅读:

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被解释为事件处理程序上的事件诱导元素。如果你在事件处理程序中调用一个函数并希望它引用它,this将不会改变,除非你使用function.call(scope)专门调用作用域。