【问题标题】:Arrow Functions and This [duplicate]箭头函数和这个[重复]
【发布时间】:2015-05-02 03:04:51
【问题描述】:

我正在尝试 ES6,并希望在我的函数中包含一个属性,就像这样

var person = {
  name: "jason",

  shout: () => console.log("my name is ", this.name)
}

person.shout() // Should print out my name is jason

但是,当我运行此代码控制台时,只会记录 my name is。我做错了什么?

【问题讨论】:

标签: javascript this ecmascript-6 arrow-functions


【解决方案1】:

简答:this 指向最近的边界 this - 在提供的代码中,this 位于封闭范围内。

更长的答案:箭头函数在创建时绑定它们的this do not have this, arguments or other special names bound at all - 在创建对象时,名称this 位于封闭范围内,而不是@987654331 @ 目的。通过移动声明可以更清楚地看到这一点:

var person = {
  name: "Jason"
};
person.shout = () => console.log("Hi, my name is", this);

当翻译成 ES5 中箭头语法的模糊近似时会更加清晰:

var person = {
  name: "Jason"
};
var shout = function() {
  console.log("Hi, my name is", this.name);
}.bind(this);
person.shout = shout;

在这两种情况下,this(对于喊函数)指向与定义 person 相同的范围,而不是函数添加到 person 对象时附加到的新范围。

不能使箭头函数以这种方式工作,但是,正如@kamituel 在his answer 中指出的那样,您可以利用 ES6 中较短的方法声明模式获得类似的空间节省:

var person = {
  name: "Jason",
  // ES6 "method" declaration - leave off the ":" and the "function"
  shout() {
    console.log("Hi, my name is", this.name);
  }
};

【讨论】:

【解决方案2】:

这里函数内部 this 的值是由箭头函数的定义位置而不是使用位置决定的。

所以this 指的是全局/窗口对象,如果没有包装在其他命名空间中

【讨论】:

    【解决方案3】:

    同意@Sean Vieira - 在这种情况下,this 绑定到全局对象(或者,如评论中所指出的,更一般地绑定到封闭范围)。

    如果您想要更短的语法,还有另一种选择 - 增强的对象文字支持属性函数的短语法。 this 将按照您的期望在那里绑定。见shout3():

    window.name = "global";
    
    var person = {
        name: "jason",
    
        shout: function () {
            console.log("my name is ", this.name);
        },
        shout2: () => {
            console.log("my name is ", this.name);
        },
        // Shorter syntax
        shout3() {
            console.log("my name is ", this.name);
        }
    };
    
    person.shout();  // "jason"
    person.shout2(); // "global"
    person.shout3(); // "jason"
    

    【讨论】:

    • 赞成,但请注意 this 不一定是全局对象。
    • @Oriol true,注意 - 我认为这是顶级代码。谢谢!
    【解决方案4】:

    问题在于 (MDN)

    箭头函数表达式 [...] 词法绑定 this 值。

    箭头函数捕获封闭上下文的 this 值。

    因此,该函数中this 的值将是您创建对象字面量的this 的值。可能在非严格模式下是window,在严格模式下是undefined

    要修复它,您应该使用普通函数:

    var person = {
      name: "jason",
      shout: function(){ console.log("my name is ", this.name) }
    }
    person.shout();
    

    【讨论】:

      【解决方案5】:

      接受的答案非常好,简洁明了,但我将详细说明 Sean Vieira 所说的内容:

      箭头函数没有 这个参数或其他特殊名称完全绑定。

      因为箭头函数没有“this”,所以它使用了父级的“this”。 "this" 始终指向父对象,而 person 对象的父对象是 Window(如果您在浏览器中)。

      为了证明它在您的控制台中运行:

      var person = {
          name: "Jason",
          anotherKey: this
      }
      console.log(person.anotherKey)
      

      您将获得 Window 对象。

      我发现这是一种非常有用的思考方式。这还不是完整的故事,因为对象字面量的“this”是另一个讨论。

      【讨论】:

      • 太棒了 - 我试图理解为什么它会发生这么长时间!!!!
      • 解释得很清楚。谢谢。
      猜你喜欢
      • 2017-02-05
      • 2018-12-31
      • 2023-03-15
      • 2018-08-02
      • 2018-07-18
      • 2017-12-06
      • 2019-05-18
      相关资源
      最近更新 更多