JavaScript - 带有传递函数的 setInterval 不识别全局变量

JavaScript - setInterval with passed function does not recognize global variables

我被困在了一些奇怪的问题中,然后这个问题很难理解为什么 Angular 会这样,运气不好 在 Google为了问题,所以我来了。

我想测试 setInterval() 函数并计算一些变量,不是太难的东西,但我遇到了无法找到解决方案或解释的问题。

这是我正在使用的代码,它工作正常:

public counter: number = 1;

  myFunction() {
    setInterval(() => {
      console.log(this.counter);
      this.counter++;
    }, 1000);
  }

Output: 1, 2, 3, 4, 5...

这段代码工作正常,但是当我把函数变成这样时,我得到 undefined 作为输出然后 Nan, Nan, Nan

public counter: number = 1;

  foo() {
    console.log(this.counter);
    this.counter++;
  }

  myFunction() {
    setInterval(this.foo, 1000);
  }

* myFunction is the starting function *

Output: undefined, Nan, Nan, Nan...

我猜 foo() 无法访问全局变量的变量访问存在一些问题,但这是怎么发生的?我该如何解决这个问题?

在第一个示例中,您传递了一个在 es6 shorthand (link here) 中声明的函数,因此 "this" 将绑定到当前作用域。

在第二个示例中,您传递了对函数的引用,因为 setTimeout 使用指向全局对象的 this 执行函数,"this" 等于 window 对象,因此属性未定义。

这是一个代码,可以按照您描述的方式运行

 class A{
 public counter: number = 1;

   foo() {
     alert(this.counter);
     this.counter++;
   }

   myFunction() {
     setInterval(this.foo, 1000);
   }
 }

 const a = new A();
 a.myFunction(); // output andefined, Nan, Nan ...

现在使用 bind 的代码:JSFiddle

 class A{
 public counter: number = 1;

   foo() {
     alert(this.counter);
     this.counter++;
   }

   myFunction() {
     setInterval(this.foo.bind(this), 1000);
   }
 }

 const a = new A();
 a.myFunction(); // output 1, 2, 3, 4 ...

这是一个非常棘手的主题,所以

先检查这个问题How to access the correct 'this' inside a callback?

以及关于该主题的几个非常好的答案 here and here .


现在是绑定方法 - Function.prototype.bind() :

(来自文档)

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

并且喜欢这个词(摘自 docs 中的示例部分):

The simplest use of bind() is to make a function that, no matter how it is called, is called with a particular this value.

A common mistake for new JavaScript programmers is to extract a method from an object, then to later call that function and expect it to use the original object as its this (e.g. by using that method in callback-based code). Without special care, however, the original object is usually lost.

Creating a bound function from the function, using the original object, neatly solves this problem