简体   繁体   English

JavaScript-具有传递函数的setInterval无法识别全局变量

[英]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 particular this 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM