【问题标题】:ES6 Arrow function: why "this" points differently when used in constructor and object literal?ES6 箭头函数:为什么“this”在构造函数和对象字面量中使用时指向不同?
【发布时间】:2020-04-19 17:22:44
【问题描述】:

我知道箭头函数从封闭范围继承this。然而,仍然无法理解为什么在对象字面量中定义的箭头函数中的this 指向全局对象,而在构造函数中指向创建的对象。 考虑以下代码:

function Obj() {
  this.show = () => {
    console.log(this);
  };
}
const o = new Obj();
const o2 = {
  show: () => {
    console.log(this);
  }
}

o.show(); // o
o2.show() // window || undefinded

【问题讨论】:

标签: javascript constructor this arrow-functions object-literal


【解决方案1】:
function Obj() {
  this.show = () => {
    console.log(this);
  };
}
const o = new Obj();
o.show(); 

这里的“this”基于“new”关键字的规则,指向一个新对象,其结构定义在 Obj() 中(新对象是上下文)。 更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

const o2 = {
  show: () => {
    console.log(this);
  }
}
o2.show() // window || undefinded

这里的“this”在运行时获取它的值,因为 lambda 函数和对象字面量都没有定义上下文,剩余的上下文是全局上下文,这就是你获得该值的原因。

【讨论】:

    【解决方案2】:

    好的,找到了答案,如“javascript ninja 的秘密”中所述:

    箭头函数没有它们的 自己的语境。相反,上下文是继承的 来自定义它们的函数。

    所以在构造函数this === {}里面。 而在定义对象字面量时,this 仍指向全局对象,如果处于严格模式,则仍指向 undefined

    【讨论】:

      【解决方案3】:

      这是因为在声明时Object 尚未初始化。您可以使用立即调用的函数表达式 (IIFFE) 或使用 Object.create 来强制初始化。比如:

      // IIFE
      const x = (() => ({a: 1, b: 2, sum() {return this.a + this.b}}))();
      console.log(`x.sum() => ${x.sum()}`);
      // Object.create
      const y = Object.create({a:1, b:2, sum() {return this.a + this.b}});
      console.log(`y.sum() => ${y.sum()}`);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-27
        • 2019-02-19
        • 2022-01-14
        相关资源
        最近更新 更多