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
What does "this" refer to in arrow functions in ES6?
提问by temporary_user_name
I've read in several places that the key difference is that this
is 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 this
is 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 this
value of the enclosing context
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, this
inside 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
动态名称绑定
this
refers 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
m
is a method because it relies on this
. o.m()
or o["m"]()
means m
is 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 m
to the function f
, you pull outm
of its object/context o
. It is uprooted now and this
refers to nothing (strict mode assumed).
它与之前的模式非常相似,只是缺少括号。但后果是可观的:当你传递m
给函数时f
,你拉出m
它的对象/上下文o
。它现在被连根拔起并且this
什么都不指(假设为严格模式)。
Lexical (or Static) Name Binding
词法(或静态)名称绑定
Arrow functions don't have their own this
/super
/arguments
binding. 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 (Window
in browsers) only functions are able to form a scope in Javascript (and {}
blocks in ES2015). When the o.foo
arrow function is called there is no surrounding function from which baz
could inherit its this
. Consequently it captures the this
binding of the global scope which is bound to the Window
object.
除了全局范围(Window
在浏览器中)之外,只有函数能够在 Javascript 中形成范围(以及{}
ES2015 中的块)。当o.foo
调用箭头函数时,没有周围的函数baz
可以继承它的this
. 因此,它捕获this
绑定到Window
对象的全局范围的绑定。
When baz
is invoked by o.bar
, the arrow function is surrounded by o.bar
(o.bar
forms its parent lexical scope) and can inherit o.bar
's this
binding. o.bar
was called on o
and thus its this
is bound to o
.
当baz
被 调用时o.bar
,箭头函数被o.bar
(o.bar
形成其父词法范围)包围,并且可以继承o.bar
的this
绑定。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 this
is 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 this
keyword
箭头函数从不与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'