4

我在以下上下文中遇到了一个小问题this

在 JavaScriptthis中,总是指我们正在执行的函数的“所有者”,或者更确切地说,指的是函数作为方法的对象。

所以,这段代码:

var o={

  f:function ()
     {
       console.log(this); //the owner of the function is `o`
     }
}

console.log(o.f()) // this shows the `o` as this

一切都好。

那么为什么这个代码

var o = {
    f: function ()
    {
        return function ()
        {
            console.log(this);
        }
    }
}
console.log(o.f()())

表明这this是全局对象/窗口?

o.f()返回一个函数,然后我执行它。但 Hoster 对象仍然是o。那么为什么它显示主机为window

4

5 回答 5

4

的值this是由你调用函数的对象决定的,而不是函数被声明的地方。

例如,如果您执行了以下操作:

var f = o.f;
console.log(f());

你会看到那this也是窗口。

您还可以执行以下操作:

var o2 = { f: o.f };
console.log(o2.f());

在那里,this将是 o2 对象,而不是 o。

在您的情况下, of 正在返回一个函数,您在没有对象引用的情况下调用该函数。在这种情况下,调用的函数被调用并this设置为全局对象(在浏览器中是window)。

如果要保留this指针,则需要在闭包中捕获它,如下所示:

var o = {
    f: function ()
    {
        var self = this;
        return function ()
        {
            console.log(self);
        }
    }
}
console.log(o.f()())

然后无论如何调用它,您都将拥有正确的对象引用。

于 2013-04-17T17:58:05.330 回答
2

不,返回的函数只是一个函数,不托管在任何对象上(this默认为全局对象)。将这种双重调用视为

var temp = o.f();
temp();

而不是那个“所有者上下文”的比喻(经常失败),最好参考MDN 对this关键字的介绍。“所有者”对象解释仅适用于您在对象上调用方法的情况 - 一旦您将函数传递(进入回调,对其进行return分配,分配它)它就会失去其上下文。

于 2013-04-17T17:57:27.887 回答
2

this由函数的调用方式设置,而不是由它的存储位置设置。

o.f()有效,因为您f()o. 如果您将该函数复制到另一个对象,this则会发生变化。

例如:

var x = {
  a: o.f
};

console.log(x.a()); // logs x, not o.  because the "context" is x

在您的第二个示例中,o.f()返回一个函数,然后在“无上下文”的情况下运行该函数。这使得“上下文”设置为window.

于 2013-04-17T17:58:34.777 回答
1

答案很简单。您正在返回一个闭包并随后在窗口范围内对其进行评估。如果你没有返回函数,你就不会有这个问题。

解决方案:

var o = {
  f: function() {
    return function() { console.log(this); }
  }
};
console.log(o.f().apply(o, []));

将关闭的所有权o从无到有 (= window)

于 2013-04-17T17:55:39.523 回答
1

当函数没有所有者时,获取本地上下文会退回到全局上下文,因为真正的上下文是undefined. 如果真实上下文是null.

在非严格模式下所有这些都是真的!

在严格模式下,获取本地上下文不会退回到其他任何东西。上下文保持原样,也就是说,在不拥有函数的情况下:undefined。意识到这一点非常重要。

于 2013-04-17T18:16:57.597 回答