简体   繁体   English

ES6 箭头函数与 ES5:如何知道使用 ES5 非箭头 function 时将“this”绑定到哪个 function

[英]ES6 Arrow functions vs ES5: how to know which function to bind `this` to when using ES5 non-arrow function

I'm reading this article on using ES6 arrow functions.我正在阅读这篇关于使用 ES6 箭头函数的文章。 It gives the following example, where you have to use bind(this) , followed by the corresponding code with arrow functions.它给出了以下示例,您必须在其中使用bind(this) ,然后是带有箭头函数的相应代码。

var obj = {
  id: 42,
  counter: function counter() {
    setTimeout(function() {
      console.log(this.id);
    }.bind(this), 1000);
  }
};

It says In the ES5 example, .bind(this) is required to help pass the this context into the function .它说In the ES5 example, .bind(this) is required to help pass the this context into the function

What I Want To Know: Why do you use bind(this) with the callback to setTimeout rather than with the counter function?我想知道的:为什么你使用bind(this)setTimeout的回调而不是counter function? ie why isn't the above code like this:即为什么上面的代码不是这样的:

var obj = {
  id: 42,
  counter: function counter() {
    setTimeout(function() {
      console.log(this.id);
    }, 1000);
  }.bind(this);
};

Why do you use bind(this) with the callback to setTimeout rather than with the counter function?为什么你使用bind(this)setTimeout的回调而不是计数器 function?

Because the counter function (which works like a method of the obj object) already has the proper this because you call it like obj.counter() so it gets this from calling it as obj.counter() .因为counter function (它的工作方式类似于obj对象的方法)已经具有正确的this ,因为您将其obj.counter() ,因此它通过将其称为obj.counter()来获取this Assuming you call counter as obj.counter() , then if you do console.log(this.id) on the first line of the counter() function, it will properly show the id value.假设您将 counter 称为obj.counter() ,那么如果您在counter() function 的第一行执行console.log(this.id) ,它将正确显示id值。

The callback you pass to setTimeout() however has no natural this value unless you use an arrow function or .bind() on the callback function itself because when setTimeout() calls your callback it does not set a specific this value (it just calls your callback as a normal function), therefore the this value goes to the default.但是,您传递给setTimeout()的回调没有自然的this值,除非您在回调 function 本身上使用箭头 function 或.bind() ,因为当setTimeout()调用您的回调时,它不会设置特定的this值(它只是调用您的回调作为普通函数),因此this值变为默认值。 That means this will be undefined if running strict mode or the global object if running in loosey-goosey mode inside of the setTimeout() callback.这意味着如果运行严格模式或全局 object 如果在setTimeout()回调内以松散-goosey 模式运行, this将是undefined的。

See the 6 ways that the value of this is set here when calling a function.调用 function 时,请参阅此处设置this值的 6 种方式。


I should also mention that if you did what you were proposing like this:我还应该提到,如果你按照你的提议做了这样的事情:

var obj = {
  id: 42,
  counter: function counter() {
    setTimeout(function() {
      console.log(this.id);
    }, 1000);
  }.bind(this);
};

Not only would it not help the setTimeout() callback at all, but it would also bind the wrong value of this to the counter() method.它不仅对setTimeout()回调没有任何帮助,而且还会将this的错误值绑定到counter()方法。 You would get whatever this was before the var obj definition (also known as the lexical value of this ).您将得到thisvar obj定义之前的任何内容(也称为this的词法值)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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