这个关键字是构造函数内部的 window 对象。

7

好的,我之前认为我理解了这个问题(不是故意搞笑),但显然并没有。

var Constructor = function () {
    var internalFunction = function () {
        return this === window;
    };
    this.myMethod = function () {
        alert(internalFunction());
    };
};
var myObj = new Constructor();
myObj.myMethod();

这会弹出 true。为什么内部函数不能将 this 视为对象?相反,我必须在 myMethod 中使用 alert(internalFunction.call(this));

编辑:我想要一个解释为什么会分配这样的 this,而不是像 var self = this; 等变通方法。如果没有表达清楚,对不起。


1
这些问题的答案都没有使用 that。我感到受到了背叛。 - hugomg
@missingno:我不喜欢“那个”。它没有描述性。话虽如此,我的答案选择也不好 :) - Tim Down
+1 for unintentional pun - LiamRyan
几年后回来...我倾向于使用构造函数的小写版本。function Note() { var note = this; 我认为这是一种非常易于阅读的约定。 - Nathan MacInnes
4个回答

6

this在函数被调用之前不会绑定,并且取决于函数的调用方式。你可以把它想象成隐式传递给函数的额外参数。

在这种情况下,问题在于你使用了internalFunction()来调用internalFunctionthis的值是通过将函数作为方法调用(例如foo.bar()foo["bar"]())或通过call()apply()显式设置this来设置的。但你的调用既不是前者也不是后者,因此this会回退到全局对象。

在保持internalFunction私有的同时,在这种情况下实现你想要的最简单的方法是在构造函数内部存储对this的引用:

var Constructor = function() {
    var thisObj = this;

    var internalFunction = function () {
        return thisObj === window;
    };

    thisObj.myMethod = function () {
        alert(internalFunction());
    };
}

啊,那就有道理了……this是在调用时赋值的,所以调用internalFunction()实际上是隐式地调用window.internalFunction()。讲解得很清楚。 - Nathan MacInnes
@jondavidjohn:我不想就这个问题进行讨论,而且这是我对原始代码进行的不必要的调整,所以我已经恢复了它。感谢您指出这一点。 - Tim Down

3

由于函数作用域规则,this在每个函数内部重新赋值...我会将您的对象存储为self的副本,并相应地使用它...

var Constructor = function () {

    var self = this;

    var internalFunction = function () {
        return self === window;
    };
    this.myMethod = function () {
        alert(internalFunction());
    };
};
var myObj = new Constructor();
myObj.myMethod();

应该会给你期望的输出结果。

注意事项

这是 JavaScript 创造的一种相当危险的做法,主要是因为如果在使用 Constructor 时忘记了 new 关键字,你的 this 引用将指向 window(全局)对象,所以你将毫不知情地将 myMethod 添加到 window 上。


2
JavaScript有五种调用函数的方式。取决于你选择哪种方式,this的值也会不同:
  1. 全局函数调用(例如myFunction())。没有显式地给出this的值。在浏览器中,this的值将是默认对象(window)。
  2. 方法调用(例如obj.myFunction())。this的值是调用该方法的对象(在这个例子中是obj)。
  3. 使用call方法(例如myFunction.call(obj))。this的值被显式地提供(在这个例子中是obj)。
  4. 使用apply方法(例如myFunction.apply(obj))。this的值被显式地提供(在这个例子中是obj)。
  5. 构造函数(例如new MyFunction())。this的值是运行时提供的新创建的对象。

这五种方式的详细解释可以在这里找到:


1

这是一个作用域问题, 尝试使用以下代码:

var Constructor = function () {
    var $this = this;
    var internalFunction = function () {
        return $this === window;
    };
    this.myMethod = function () {
        alert(internalFunction());
    };
};
var myObj = new Constructor();
myObj.myMethod();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接