当提供箭头函数时,'this' 如何在 Array.prototype.forEach 中解析?

How is 'this' resolved in Array.prototype.forEach when an arrow function in provided?

这是我的代码:

class Employee {
  constructor(ename) {
    this.ename = ename;
  }
}

class EmployeeRenderer {
  constructor(employees) {
    this.employees = employees;
    this.ename = "EmployeeRenderer";
  }
  renderWithArrowFunc() {
    this.employees.forEach(emp => {
      console.log(this.ename); // Will print EmployeeRenderer 3 times
    })
  }
}


var employees = [
  new Employee('Alex'),
  new Employee('Bob'),
  new Employee('Smith')
];

var employeeRenderer = new EmployeeRenderer(employees);
employeeRenderer.renderWithArrowFunc();

我们知道,在箭头函数中,this 不是声明的变量,因此要解析对 this 的引用,JavaScript 会咨询封闭范围.因此,在上面的代码中,当 console.log(this.ename) 被执行时,JavaScript 询问第一个直接封闭的词法范围——函数 forEach——关于 this。在 forEach 实现** 中,this 指向调用函数的数组的值:employees 并且因为它没有 ename 属性,所以我希望在输出中看到 undefinedEmployeeRenderer 多 3 倍。表明this已经解析为EmployeeRenderer.ename。我在这里错过了什么?

** 我搜索了 forEach 的实现,但找不到,因此我认为它必须与 MDN 中提到的 pollyfill 相同。

变量范围是词法forEach 的代码与确定回调函数中变量的范围无关。它只是在文本上包含箭头函数定义的代码,以及它周围的块,等等。

所以this指的是用来调用returnWithArrowFunct()的上下文,也就是employeeRenderer变量的值。

this没有属性ename指向外this。要获得一个值,您需要取 emp.ename

class Employee {
  constructor(ename) {
    this.ename = ename;
  }
}

class EmployeeRenderer {
  constructor(employees) {
    this.employees = employees;
  }
  renderWithArrowFunc() {
    this.employees.forEach(emp => {
      console.log(emp.ename); // Will print Alex, Bob, Smith
    })
  }
}


var employees = [
  new Employee('Alex'),
  new Employee('Bob'),
  new Employee('Smith')
];

var employeeRenderer = new EmployeeRenderer(employees);
employeeRenderer.renderWithArrowFunc();