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
我被困在了一些奇怪的问题中,然后这个问题很难理解为什么 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 particularthis
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