简体   繁体   English

Javascript 箭头 function 词法 scope:ZA8CFDE6331BD59EB2AC96F8911C4B666 字面量与“新”运算符

[英]Javascript arrow function lexical scope: object literal vs “new” operator

I'm trying to understand how arrow functions work in JS.我试图了解箭头函数在 JS 中是如何工作的。 One thing that confuses me is:让我困惑的一件事是:

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"

Can somebody please explain why object literal does not create a new scope, while calling "new" does?有人可以解释为什么 object 文字不会创建新的 scope,而调用“新”会吗? (I always thought object literal and "new" operator are equal; I didn't find proper explanation in MDN.) I found this explanation on how new operator works . (我一直认为 object 字面量和“new”运算符是相等的;我在 MDN 中没有找到正确的解释。)我找到了关于 new 运算符如何工作的解释。 But it's not clear to me why object literal works differently.但我不清楚为什么 object 文字的工作方式不同。

Thanks in advance!提前致谢!

The new operator doesn't create a new scope. new运算符不会创建新的 scope。

Functions create a new scope.函数创建一个新的 scope。

The constructor function is a different function to the global-outside-of-any-function space. constructor function 是与全局外部任意函数空间不同的 function。

So whenever you are using arrow function anywhere it will not have this of its own because it will refer this from its parent function(to be simple).因此,每当您在任何地方使用箭头 function 时,它都不会拥有自己的this ,因为它会从其父函数中引用this (简单起见)。

So in first case its referring this of window and hence undefined .因此,在第一种情况下,它指this是 window ,因此是undefined

In second case is referring 'this' of constructor and hence 'benny'.在第二种情况下,指的是构造函数的“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();

I wanted to bring up this example because I thought it was quite interesting -- this isn't meant as an answer to your question directly, but just some additional info.我想提出这个例子是因为我认为它很有趣——这并不是直接回答你的问题,而只是一些额外的信息。

People were talking about how defining it inside the constructor makes the this property refer to the object itself -- because that's what this means in a constructor, So I wanted to see what would happen if you define an arrow function in the way I've done above, with getName2 -- it's not in the constructor, but it still gets this defined as the object itself.人们在谈论如何在构造函数中定义它使this属性引用 object 本身——因为this就是在构造函数中的意思,所以我想看看如果你以我的方式定义箭头 function 会发生什么上面用getName2完成——它不在构造函数中,但它仍然将this定义为 object 本身。 So... why?所以为什么?

Well, it turns out when you define arrow functions in that manner, it actually DOES end up being defined in the constructor.好吧,事实证明,当您以这种方式定义箭头函数时,它实际上最终是在构造函数中定义的。 I think there's some kind of code hoisting going on with arrow functions like that.我认为像这样的箭头函数正在进行某种code hoisting You can actually verify it by trying to change the function on the prototype:您实际上可以通过尝试更改原型上的 function 来验证它:

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

You can't change the function of getName2 via the prototype, because that function actually gets defined in the constructor behind the scenes.您不能通过原型更改 getName2 的getName2 ,因为 function 实际上是在幕后的构造函数中定义的。

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

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