该关键字是构造函数中的窗口对象

this keyword is window object within a constructor function

本文关键字:窗口 对象 构造函数 关键字      更新时间:2023-09-26

好吧,我以为我明白了(没有双关语的意思),但显然不是。

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;等。抱歉我没说清楚

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在每个函数中被重新分配…我会将您的对象的副本存储为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 (god)对象,因此您将在没有警告的情况下将myMethod附加到窗口。

在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的值是运行时提供的新创建的对象。

在这里更详细地解释了这五个:

  • http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx

这是一个范围问题,尝试如下:

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