回调函数的作用域/this

Scope / this of callback function

我理解函数的范围应该在定义时确定。

所以根据我的理解,function(toy) 的范围应该是 forEach 的范围,所以 this 真的应该只是 forEach 吗?但事实证明它是全球范围的。不明白为什么

function Cat(name) {
  this.name = name;
  this.toys = ['string', 'ball', 'balloon'];
};

Cat.prototype.play = function meow() {
  this.toys.forEach(function(toy) {
    console.log(this);
  });
};

const garfield = new Cat('garfield');
garfield.play();

当您使用 ES5 语法声明 function() 时,它不知道词法范围,因此 this 绑定到默认值 window。

这与您声明一个命名的全局函数然后通过引用将其传入完全一样。唯一的区别是您将代码声明为内联。

在 .prototype 链上声明的函数会自动绑定到它们的父对象。

如果您使用新的 ES6 语法 () => {},那么 this 将绑定到当前词法范围。

正如其他人所指出的,使用 function 关键字声明的函数将拥有自己的 this,并且取决于函数的调用方式,而不是其定义的上下文。由于您正在使用 .forEach()(并且似乎倾向于 es5 语法),因此在 forEach() 方法中更改 this 的一种可能方法是使用 thisArg,其中你可以明确说明 this 应该在你的回调函数中:

function Cat(name) {
  this.name = name;
  this.toys = ['string', 'ball', 'balloon'];
};

Cat.prototype.play = function meow() {
  this.toys.forEach(function(toy) {
    console.log(this);
  }, this);
  //  ^--- specify the thisArg
};

const garfield = new Cat('garfield');
garfield.play();