javascript 箭头函数和 this

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28798330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:35:13  来源:igfitidea点击:

Arrow Functions and This

javascriptthisecmascript-6arrow-functions

提问by jason328

I'm trying out ES6 and want to include a property inside my function like so

我正在尝试 ES6 并希望在我的函数中包含一个属性

var person = {
  name: "jason",

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

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

However, when I run this code console only logs my name is. What am I doing wrong?

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

回答by Sean Vieira

Short answer: thispoints at the nearest bound this- in the code provided thisis found in the enclosing scope.

简短回答:this指向最近的边界this- 在提供的代码this中找到封闭范围。

Longer answer: Arrow functions bind their thiswhen they are createddo not have this, argumentsor other special names bound at all- when the object is being created the name thisis found in the enclosing scope, not the personobject. You can see this more clearly by moving the declaration:

更长的答案:箭头函数 this在创建时绑定它们没有thisarguments或结合其它特殊名字-正在创建对象时的名称this是在封闭的范围内,没有找到person对象。您可以通过移动声明更清楚地看到这一点:

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

And even more clear when translated into a vague approximation of the arrow syntax in ES5:

当翻译成 ES5 中箭头语法的模糊近似时,就更清楚了:

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

In both cases, this(for the shout function) points to the same scope as personis defined in, not the new scope that the function is attached to when it is added to the personobject.

在这两种情况下,this(对于shout 函数)都指向与person定义相同的作用域,而不是函数被添加到person对象时附加到的新作用域。

You cannotmake arrow functions work that way, but, as @kamituel points out in his answer, you cantake advantage of the shorter method declaration pattern in ES6 to get similar space savings:

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

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

回答by kamituel

Agreed with @Sean Vieira - in this case thisis bound to the global object (or, as pointed out in the comment, more generally to an enclosing scope).

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

If you want to have a shorter syntax, there is another option - enhanced object literals support short syntax for property functions. thiswill be bound as you expect there. See shout3():

如果您想要更短的语法,还有另一个选择——增强的对象字面量支持属性函数的简短语法。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"

回答by Tenbrink

The accepted answer is excellent, concise, and clear but i will elaborate a little on what Sean Vieira said:

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

Arrow functions do not have this arguments or other special names bound at all.

箭头函数根本没有绑定此参数或其他特殊名称。

Because the arrow function doesn't have a "this", it uses the parent's "this". "this" always points to the parent, and the parent of the person object is Window (if you're in a browser).

因为箭头函数没有“this”,它使用父的“this”。“this”总是指向父对象,而person对象的父对象是Window(如果你在浏览器中)。

To prove it run this in your console:

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

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

You'll get the Window object.

您将获得 Window 对象。

I find this to be a really helpful way to think about it. It isn't quite the full story, as what the "this" of an object literal is is another discussion.

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

回答by A.B

Here the value of this inside of the function is determined by where the arrow function is defined not where it is used.

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

So thisrefers to global/window object if not wrapped in other namespace

因此this,如果未包装在其他命名空间中,则引用 global/window 对象

回答by Oriol

The problem is that (MDN)

问题是(MDN

An arrow function expression [...] lexically binds the this value.

Arrow functions capture the this value of the enclosing context.

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

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

Therefore, the value of thisin that function will be the value of thiswhere you create the object literal. Probably, that will be windowin non-strict mode and undefinedin strict mode.

因此,该this函数中的值将是this您创建对象字面量的位置的值。可能,这将window处于非严格模式和undefined严格模式。

To fix it, you should use a normal function:

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

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