javascript ES6 中的箭头函数中的“this”指的是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28371982/
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 08:52:13  来源:igfitidea点击:

What does "this" refer to in arrow functions in ES6?

javascriptthisecmascript-6arrow-functions

提问by temporary_user_name

I've read in several places that the key difference is that thisis lexically bound in arrow functions. That's all well and good, but I don't actually know what that means.

我在几个地方读到过,关键区别在于this箭头函数中的词法绑定。这一切都很好,但我实际上不知道这意味着什么。

I know it means it's unique within the confines of the braces defining the function's body, but I couldn't actually tell you the output of the following code, because I have no idea what thisis referring to, unless it's referring to the fat arrow function itself....which doesn't seem useful.

我知道这意味着它在定义函数主体的大括号范围内是唯一的,但我实际上无法告诉您以下代码的输出,因为我不知道this指的是什么,除非它指的是粗箭头函数本身......这似乎没有用。

var testFunction = () => { console.log(this) };
testFunction();

采纳答案by Dave

Arrow functions capture the thisvalue of the enclosing context

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

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

So, to directly answer your question, thisinside your arrow function would have the same value as it did right before the arrow function was assigned.

因此,为了直接回答您的问题,this您的箭头函数内部的值将与分配箭头函数之前的值相同。

回答by Dave

In order to provide the big picture I'm going to explain both, dynamic and lexical binding.

为了提供大图,我将解释动态绑定和词法绑定。

Dynamic Name Binding

动态名称绑定

thisrefers to the object the method is called on. This is a regularly to be read sentence on SO. But it is still only a phrase, pretty abstract. Is there a corresponding code pattern to this sentence?

this指的是调用该方法的对象。这是一个经常被阅读的关于 SO 的句子。但它仍然只是一个短语,相当抽象。这句话有对应的码型吗?

Yes there is:

就在这里:

const o = {
  m() { console.log(this) }
}

// the important patterns: applying methods

o.m(); // logs o
o["m"](); // logs o

mis a method because it relies on this. o.m()or o["m"]()means mis applied to o. These patterns are the Javascript translation to our famous phrase.

m是一种方法,因为它依赖于this. o.m()o["m"]()手段m适用于o。这些模式是我们著名短语的 Javascript 翻译。

There is another important code pattern that you should pay attention to:

您应该注意另一个重要的代码模式:

"use strict";

const o = {
  m() { console.log(this) }
}

// m is passed to f as a callback
function f(m) { m() }

// another important pattern: passing methods

f(o.m); // logs undefined
f(o["m"]); // logs undefined

It is very similar to the previous pattern, only the parenthesis are missing. But the consequences are considerable: When you pass mto the function f, you pull outmof its object/context o. It is uprooted now and thisrefers to nothing (strict mode assumed).

它与之前的模式非常相似,只是缺少括号。但后果是可观的:当你传递m给函数时f,你拉出m它的对象/上下文o。它现在被连根拔起并且this什么都不指(假设为严格模式)。

Lexical (or Static) Name Binding

词法(或静态)名称绑定

Arrow functions don't have their own this/super/argumentsbinding. They inherit them from their parent lexical scope:

箭头函数没有自己的this/ super/arguments约束力。它们从它们的父词法范围继承它们:

const toString = Object.prototype.toString;

const o = {
  foo: () => console.log("window", toString.call(this)),
      
  bar() {
    const baz = () => console.log("o", toString.call(this));
    baz();
  }
}

o.foo() // logs window [object Window]
o.bar() // logs o [object Object]

Apart from the global scope (Windowin browsers) only functions are able to form a scope in Javascript (and {}blocks in ES2015). When the o.fooarrow function is called there is no surrounding function from which bazcould inherit its this. Consequently it captures the thisbinding of the global scope which is bound to the Windowobject.

除了全局范围(Window在浏览器中)之外,只有函数能够在 Javascript 中形成范围(以及{}ES2015 中的块)。当o.foo调用箭头函数时,没有周围的函数baz可以继承它的this. 因此,它捕获this绑定到Window对象的全局范围的绑定。

When bazis invoked by o.bar, the arrow function is surrounded by o.bar(o.barforms its parent lexical scope) and can inherit o.bar's thisbinding. o.barwas called on oand thus its thisis bound to o.

baz被 调用时o.bar,箭头函数被o.bar(o.bar形成其父词法范围)包围,并且可以继承o.barthis绑定。o.bar被调用o,因此它this必然是o

回答by Xin

Hope this code show could give you clearer idea. Basically, 'this' in arrow function is the current context version of 'this'. See the code:

希望这个代码展示能给你更清晰的想法。基本上,箭头函数中的“this”是“this”的当前上下文版本。看代码:

// 'this' in normal function & arrow function
var this1 = {
    number: 123,
    logFunction: function () { console.log(this); },
    logArrow: () => console.log(this)
};
this1.logFunction(); // Object { number: 123}
this1.logArrow(); // Window 

回答by Alireza

Arrow function thisis pointing to the surrounding parent in Es6, means it doesn't scope like anonymous functions in ES5...

箭头函数this在 Es6 中指向周围的父级,这意味着它不像 ES5 中的匿名函数那样作用域......

It's very useful way to avoid assigning var self to this which is widely used in ES5...

这是避免将 var self 分配给 ES5 中广泛使用的 this 的非常有用的方法......

Look at the example below, assigning a function inside an object:

看下面的例子,在一个对象中分配一个函数:

var checkThis = {
  normalFunction: function () { console.log(this); },
  arrowFunction: () => console.log(this)
};

checkThis.normalFunction(); //Object {}
checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…}

回答by Plasmatium

You can try to understand it by following the way below

您可以尝试按照以下方式理解它

// whatever here it is, function or fat arrow or literally object declare
// in short, a pair of curly braces should be appeared here, eg:
function f() {
  // the 'this' here is the 'this' in fat arrow function below, they are
  // bind together right here
  // if 'this' is meaningful here, eg. this === awesomeObject is true
  console.log(this) // [object awesomeObject]
  let a = (...param) => {
    // 'this is meaningful here too.
    console.log(this) // [object awesomeObject]
}

so 'this' in fat arrow function is not bound, means you can not make anything bind to 'this' here, .apply won't, .call won't, .bind won't. 'this' in fat arrow function is bound when you write down the code text in your text editor. 'this' in fat arrow function is literally meaningful here. What your code write here in text editor is what your app run there in repl. What 'this' bound in fat arror will never change unless you change it in text editor. Sorry for my pool English...

所以胖箭头函数中的'this'没有绑定,意味着你不能在这里绑定'this',.apply不会,.call不会,.bind不会。当您在文本编辑器中写下代码文本时,胖箭头函数中的“this”会被绑定。胖箭头函数中的“this”在这里具有字面意义。您在文本编辑器中编写的代码就是您的应用程序在 repl 中运行的内容。除非您在 text editor 中更改它,否则在 fat arror 中绑定的“this”永远不会改变。对不起我的游泳池英语...

回答by Hamit YILDIRIM

In another example, if you click the age button below

在另一个示例中,如果您单击下面的年龄按钮

<script>
var person = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: function() {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

var person2 = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: () => {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

</script>



<input type=button onClick="alert(person2.age());" value="Age">

it will throw an exception like this

它会抛出这样的异常

×JavaScript error: Uncaught TypeError: Cannot read property 'getFullYear' of undefined on line 18

×JavaScript 错误:未捕获的类型错误:无法读取第 18 行未定义的属性“getFullYear”

But if you change person2's this line

但是如果你改变person2的这一行

return new Date().getFullYear() - this.dob.getFullYear(); 

to

return new Date().getFullYear() - person2.dob.getFullYear();

it will work because this scope has changed in person2

它会起作用,因为这个范围在 person2 中发生了变化

回答by TrickOrTreat

Arrow function never binds with thiskeyword

箭头函数从不与this关键字绑定

var env = "globalOutside";
var checkThis = {env: "insideNewObject", arrowFunc: () => {
console.log("environment: ", this.env);
} }

checkThis.arrowFunc()   // expected answer is environment: globalOutside

// Now General function 
var env = "globalOutside";
var checkThis = {env: "insideNewObject", generalFunc: function() {
console.log("environment: ", this.env);
} }
checkThis.generalFunc() // expected answer is enviroment: insideNewObject

// Hence proving that arrow function never binds with 'this'