0

此代码生成 x 未定义

var myobj1 = 
{  
    x:9, 
    myfunction:function()
    {
        if(this === window) 
            alert("x is not Defined");
        else if (this === myobj1)
            alert(this.x);
        else
            alert("Error!");
    }
}

function test()
{
    setTimeout(myobj1.myfunction, 1000);
}

test();

而此代码生成 x=9 作为输出

var myobj1 = 
{  
    x:9, 
    myfunction:function()
    {
        if(this === window) 
            alert("x is not Defined");
        else if (this === myobj1)
            alert(this.x);
        else
            alert("Error!");
    }
}

function test()
{
    setTimeout(function()
    {
        myobj1.myfunction()
    },  1000); 
}

有人可以解释一下为什么“如果在测试方法中没有使用回调方法,那么就会调用全局窗口对象”和“在这种情况下回调方法的意义是什么”?

4

1 回答 1

1

当你传递myobj1.myfunctionsetTimeout()时,它只传递了函数引用。与该对象的任何连接都将丢失。 setTimeout()没有能力在任何特定对象的上下文中调用它的函数引用。因此,您必须通过传递您自己的函数来自己完成,该函数将在对象的上下文中调用该方法,或者您可以.bind()在现代浏览器中使用它来做同样的事情。

当你这样做时:

setTimeout(myobj1.myfunction, 1000);

javascript 解释器获取函数引用myobj1.myfunction并将其传递给setTimeout(). 它生成与此相同的结果:

var fn = myobj1.myfunction;
setTimeout(fn, 1000);

当它被传递给 时setTimeout(),它只是一个函数引用,并且不像fn()在任何对象的上下文中那样被调用。请记住,对象上的方法“只是”对象的一个​​属性,它恰好是一个函数。函数内部的this指针取决于它的调用方式。如果没有像 in 那样使用对象上下文调用它或使用ormyobj1.myfunction()显式调用它,那么指针将不是您的对象。.apply().call()this

正如您所发现的,您可以创建自己的小存根函数,该函数将在适当对象的上下文中调用它。在现代浏览器中,你也可以.bind()这样使用:

setTimeout(myobj1.myfunction.bind(myobj1), 1000);

它与第二个代码示例中的存根函数基本上做同样的事情。

于 2013-04-07T17:12:26.687 回答