无法使用“this”访问该对象。`this` 指向 `window` 对象

Shu*_*hya 4 javascript oop jquery object

我有这个 Javascript 构造函数 -

function TestEngine() {
    this.id='Foo';
}

TestEngine.prototype.fooBar = function() {
    this.id='bar';
    return true;
}

TestEngine.prototype.start = function() {
    this.fooBar();
}

TestEngine.prototype.startMethod = function() {
    inter = setInterval(this.start, 200);
}

var test = new TestEngine();
test.startMethod();
Run Code Online (Sandbox Code Playgroud)

给我这个错误 -

Uncaught TypeError: Object [object global] has no method 'fooBar' 
Run Code Online (Sandbox Code Playgroud)

我尝试console.log发现,当我this.start从内部调用时setIntervalthis指向该window对象。为什么会这样呢?

Aad*_*hah 5

this根据上下文,指针可以指向许多事物之一:

  1. 在构造函数中(前面带有 的函数调用newthis指向新创建的构造函数实例。
  2. 当函数作为对象的方法被调用时(例如obj.funct()),this函数内部的指针就指向该对象。
  3. 您可以this使用call,apply或显式设置指向的内容bind
  4. 如果以上都没有,则this指针默认指向全局对象。在浏览器中,这就是window对象。

在你的情况下,你正在调用this.startinside setInterval。现在考虑这个虚拟实现setInterval

function setInterval(funct, delay) {
    // native code
}
Run Code Online (Sandbox Code Playgroud)

重要的是要了解这start不被称为this.start. 它被称为funct. 就像做这样的事情:

var funct = this.start;
funct();
Run Code Online (Sandbox Code Playgroud)

现在,这两个函数通常会执行相同的操作,但有一个小问题 -指针在第二种情况下指向全局对象,而在第一种情况下this指向当前对象。this

一个重要的区别是我们正在讨论this内部的指针start。考虑:

this.start();           // this inside start points to this
var funct = this.start;
funct();                // this inside funct (start) point to window
Run Code Online (Sandbox Code Playgroud)

这不是一个错误。这就是 JavaScript 的工作方式。当您将函数作为对象的方法调用时(请参阅上面的第二点),this函数内的指针指向该对象。

在第二种情况下,由于funct没有作为对象的方法调用,因此默认应用第四条规则。因此this指向window.

start您可以通过绑定到当前this指针然后将其传递给来解决此问题,setInterval如下所示:

setInterval(this.start.bind(this), 200);
Run Code Online (Sandbox Code Playgroud)

就是这样。希望这个解释能帮助您更多地了解 JavaScript 的强大之处。