JS Query-全局窗口对象

时间:2013-04-07 17:04:01

标签: javascript

This code generates x is not defined

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();

Whereas this code generates x=9 as output

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); 
}

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

1 个答案:

答案 0 :(得分:1)

当您将myobj1.myfunction传递给setTimeout()时,它只传递了函数引用。与对象的任何连接都将丢失。 setTimeout()无法在任何特定对象的上下文中调用它的函数引用。因此,您必须通过传递自己的函数来自己完成,该函数将在对象的上下文中调用该方法,或者您可以在现代浏览器中使用.bind()来执行相同的操作。

执行此操作时:

setTimeout(myobj1.myfunction, 1000);

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

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

当它传递给setTimeout()时,它只是一个函数引用,并且在任何对象的上下文中都不像fn()那样调用。请记住,对象上的方法“恰好”是恰好是函数的对象的属性。函数内的this指针由其调用方式决定。如果未使用myobj1.myfunction()中的对象上下文调用或使用.apply().call()显式调用,则this指针将不是您的对象。

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

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

在第二个代码示例中,与您的存根函数基本相同。