我遇到了一些奇怪的问题,然后问题就明白了为什么Angular会像这样行事,没有多少运气在谷歌搜索问题,所以我在这里。< / p>
我想测试setInterval()
函数并计算一些变量,而不是太难,我陷入了无法找到解决方案或解释的问题。
这是我正在使用的代码,它运行正常:
public counter: number = 1;
myFunction() {
setInterval(() => {
console.log(this.counter);
this.counter++;
}, 1000);
}
Output: 1, 2, 3, 4, 5...
这段代码工作正常,但是当我把这个函数变成这样的时候,我得到了未定义的输出,然后是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()无法访问全局变量,但是这是怎么回事?我该如何解决这个问题?
答案 0 :(得分:2)
这里的代码就像你描述的一样
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 ...
现在代码使用绑定: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?
现在绑定方法 - Function.prototype.bind():
(来自文档)
bind()
方法创建一个新函数,在调用时,将其this关键字设置为提供的值,并在调用新函数时提供任何前面提供的给定参数序列。
并喜欢这个expletetion(摘自docs中的示例部分):
bind()
的最简单用法是创建一个函数,无论它如何调用,都使用特定的this
值调用。新JavaScript程序员的一个常见错误是从对象中提取方法,然后调用该函数并期望它将原始对象用作
this
(例如,在回调中使用该方法)码)。 但是,如果没有特别小心,原始对象通常会丢失。使用原始对象从函数创建绑定函数,巧妙地解决了这个问题
答案 1 :(得分:1)
在第一个示例中,您传递的是以es6简写(链接here)声明的函数,因此"this"
将绑定到当前范围。
在第二个示例中,您正在传递对函数的引用,并且因为setTimeout
执行函数,并指向全局对象,"this"
等于窗口对象,因此属性未定义。 / p>