Javascript 箭头函数词法作用域:对象字面量 vs "new" 运算符

Javascript arrow function lexical scope: object literal vs "new" operator

我想了解箭头函数在 JS 中的工作原理。让我困惑的一件事是:

let obj1 = { // MDN states that object literal does not create a new scope but I didn't find 
             // any detailed explanation why
  name: "benny",
  getName: () => {
    console.log(this.name);
  },
};
obj1.getName(); // prints "undefined"

class myObj {
  constructor() {
    this.name = "benny";
    this.getName = () => {
      console.log(this.name);
    };
  }
}
let obj2 = new myObj();
obj2.getName(); //prints "benny"

有人可以解释为什么对象字面量不创建新范围,而调用“new”会创建吗? (我一直认为对象字面量和“new”运算符是相等的;我没有在 MDN 中找到合适的解释。) 我在 how new operator works 上找到了这个解释。但我不清楚为什么对象文字的工作方式不同。

提前致谢!

new 运算符不会创建新范围。

函数创建新作用域。

constructor 函数与 global-outside-of-any-function space 不同。

因此,无论何时您在任何地方使用箭头函数,它都不会拥有自己的 this,因为它会从其父函数引用 this(简单来说)。

所以在第一种情况下,它指的是 window 的 this,因此 undefined

在第二种情况下引用 'this' 构造函数,因此 'benny'。

class myObj {
  constructor() {
    this.name = "benny";
  }

  getName() {
    console.log(this.name);
  }

  getName2 = () => {
    console.log(this.name);
  }
}

let obj2 = new myObj();
obj2.getName();
obj2.getName2();

我想举这个例子是因为我觉得它很有趣 -- 这并不是要直接回答你的问题,而只是一些额外的信息。

人们在谈论如何在构造函数中定义它使得 this 属性 引用对象本身——因为这就是 this 在构造函数中的意思!所以我想看看如果你按照我上面所做的方式定义箭头函数会发生什么,getName2——它不在构造函数中,但它仍然被定义为对象 this本身。那么...为什么?

好吧,事实证明,当您以这种方式定义箭头函数时,它实际上最终是在构造函数中定义的。我认为像这样的箭头函数会发生某种 code hoisting 的情况。您实际上可以通过尝试更改原型上的功能来验证它:

myObj.prototype.getName = () => {console.log('hello world')}
myObj.prototype.getName2 = () => {console.log('hello world')}
obj2.getName(); // this prints 'hello world'
obj2.getName2(); // this does not

您不能通过原型更改 getName2 的函数,因为该函数实际上是在幕后的构造函数中定义的。