[英]JavaScript - setInterval with passed function does not recognize global variables
I was stuck in some weird problem and then the problem got a challenge to understand why Angular behaves like this, there was no much luck searching at Google for the problem, so I am here. 我陷入了一个奇怪的问题,然后这个问题面临一个挑战,即要理解Angular为何会这样,在Google上搜索该问题并没有太多运气 ,所以我在这里。
I wanted to test setInterval()
function and counter some variable, not something too hard, and I got stuck in problem that I couldn't find solution for or explaination. 我想测试
setInterval()
函数并计数器一些变量,而不是太难了,而我陷入了无法找到解决方案或解释的问题。
This is my code I am using and it works fine: 这是我正在使用的代码,它可以正常工作:
public counter: number = 1;
myFunction() {
setInterval(() => {
console.log(this.counter);
this.counter++;
}, 1000);
}
Output: 1, 2, 3, 4, 5...
This code works fine, but when I am taking the function to be like this, I get undefined as output and then Nan, Nan, Nan
. 这段代码可以正常工作,但是当我采用这样的功能时,我未定义为输出,然后是
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...
I guess there is some problem with variables access that foo() cannot access the global variables, but how is that happening? 我想变量访问存在一些问题,即foo()无法访问全局变量,但是这是怎么回事? and how can I fix this problem?
以及如何解决此问题?
here's a code that acts as you discribed 这是您所描述的代码
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 ...
now the code using bind : JSFiddle 现在使用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 ...
this is a very tricky subject so 这是一个非常棘手的主题,所以
first check this question How to access the correct 'this' inside a callback? 首先检查此问题。 如何在回调中访问正确的“ this”?
and couple of insanely good answer about the subject here and here . 和情侣这个话题出奇好的答案在这里和这里 。
now the bind method - Function.prototype.bind() : 现在绑定方法-Function.prototype.bind() :
(from the docs) (来自文档)
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.bind()
方法创建一个新函数,该函数在被调用时将其关键字设置为提供的值,并在调用新函数时提供给定的参数序列。
and loved this expletetion (took from the Examples part in the docs ) : 并喜欢这种删除方式(取自docs中的Examples部分):
The simplest use of
bind()
is to make a function that, no matter how it is called, is called with a particularthis
value.bind()
的最简单用法是创建一个函数,无论该函数如何调用,都使用特定的this
值进行调用。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
(eg by using that method in callback-based code).新的JavaScript程序员一个常见的错误是从一个对象中提取的方法,然后在以后调用该函数,并期望它使用原来的对象作为
this
(例如,通过使用基于回调的代码,方法)。 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
使用原始对象从函数创建绑定函数可以很好地解决此问题
In the first example you are passing a function declared in es6 shorthand (link here ), therefore "this"
will be bound to the current scope. 在第一个示例中,您传递了以es6简写形式声明的函数(链接此处 ),因此,
"this"
将绑定到当前作用域。
In the second example you are passing a reference to a function and because setTimeout
executes the function with this pointing to the global object, "this"
equals the window object and therefore the properties are undefined. 在第二个示例中,您传递了对函数的引用,并且由于
setTimeout
在指向全局对象的情况下执行该函数,因此"this"
等于窗口对象,因此属性未定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.