这个嵌套的函数

时间:2012-06-30 10:40:31

标签: javascript scope this

直到现在,为了清楚地理解我正在考虑这个总是引用该函数的所有者。

我考虑的主要有三个案例。

  1. 实例方法,这是调用方法的实例。
  2. 事件处理程序,element是调用事件的函数的所有者。
  3. 函数在全局命名空间中,window是函数的所有者
  4. 但是当我创建一个内部函数并在那里调用该函数时会发生什么。即使在这种情况下,这也指的是窗口。

    function outer(){
        var inner = (function(){
            console.log(this);
        })
        inner();
    }
    
    outer();
    

    任何人都可以用简单的术语解释为什么这会引用窗口。

2 个答案:

答案 0 :(得分:3)

您正在考虑OO术语,但您发布的代码不是OO。正如Rob W在帖子中所说,默认this在严格模式下为windowundefined

this仅更改特定功能或情境在上下文中为其提供的值。

在类模拟中使用函数,即实例化(通过new)而不是简单地调用,this指向实例,正如您所期望的那样。

function Dog(name) {
    this.name = name;
    alert(name);
}
var fido = new Dog('Fido'); //alerts 'Fido'

this提供上下文的其他情况包括事件处理程序(至少在addEventListener模型中,而不是旧的IE)以及任何时候使用call()apply()并自己手动设置this上下文。

另外,不要认为this指向JavaScript中的函数'owner'。在一个事件中,this指向受影响的元素,但将该元素视为“拥有”回调函数是没有用的 - 它只是在该元素的上下文中运行。

最后,正如昆汀所提到的,没有办法引用this的外部背景。您必须先将其缓存在变量中。

function Dog() {
    var that = this;
    setTimeout(function() {
        alert(this); //window - setTimeout() has overwritten the 'this' context
        alert(that); //we reference our cached, outer context
    }, 500);
}
var fido = new Dog('Fido');

答案 1 :(得分:1)

this(在没有newbindcallapply魔法的情况下)指的是调用该函数的对象。

如果没有对象,则使用默认对象。对于Web浏览器,该对象为window

// all comments apply to "inside the body of the bar function"
foo.bar();     // this is foo
foo.baz.bar(); // this is baz
bar();         // this is window

您可以将this的值复制到您正在调用的函数范围内的另一个变量。

function outer(){
    var that = this;
    var inner = (function(){
        console.log(that);
    })
    inner();
}

outer();

...您可以使用各种方法更改this的值。

function outer(){
    var inner = (function(){
        console.log(this);
    })
    inner.apply(this);
}

outer();