[英][reactjs]Anonymous function definitions not equivalent
I am new to React. 我是React的新手。 I encountered a strange problem while I am following the "Quick Start" of React official page https://facebook.github.io/react/docs/state-and-lifecycle.html .
我在遵循React官方页面的“快速入门” https://facebook.github.io/react/docs/state-and-lifecycle.html时遇到了一个奇怪的问题。 You can try on CodePen here: http://codepen.io/gaearon/pen/amqdNA?editors=0010
您可以在此处尝试使用CodePen: http ://codepen.io/gaearon/pen/amqdNA?editors=0010
In this code snippet 在此代码段中
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
it uses arrow function syntax to define a function which would be executed repeatedly, by passing the anonymous function object as the first argument of setInterval()
. 通过使用匿名函数对象作为
setInterval()
的第一个参数,它使用箭头函数语法定义了可以重复执行的函数。
Since I am a curious guy, I tried several different ways to pass an "equivalent" function object as the first argument. 因为我是一个好奇的人,所以我尝试了几种不同的方法将“等效”功能对象作为第一个参数传递。 But none of my ways works.
但是我的方法都不行。
componentDidMount() {
this.timerID = setInterval(
this.tick, // This cannot work in CodePen
//function () {
//this.tick();
//}, // No
//function () {
//return this.tick();
//}, // No
//() => this.tick(), // This is the official way that works
//() => {this.tick();}, // This also works, but notice the difference between this and the last one
//() => {this.tick()}, // Also works
//() => {return this.tick();}, // Also works, think it equivalent as official one
1000
);
}
I think in a pure Javascript code snippet, all these ways are valid for setInterval
to work. 我认为在纯Javascript代码段中,所有这些方法对于
setInterval
都是有效的。 Especially, as the official document ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions ) says, the arrow function definition is generally equivalent to the function () { ... }
definition. 特别是,如官方文档( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions )所述,箭头函数定义通常等效于
function () { ... }
定义。 But they just seem not equivalent in React and Babel. 但是它们在React和Babel中似乎并不等效。
After I examined the compiled Javascript code by Babel, they differ by a _this2
object. 在我检查了Babel编译的Javascript代码之后,它们之间的区别在于
_this2
对象。
// Javascript compiled by Babel
Clock.prototype.componentDidMount = function componentDidMount() {
var _this2 = this;
this.timerID = setInterval(
//this.tick // This is the compiled code using one of my way
/*function () {
this.tick();
},*/ // This is another one
function () {
return _this2.tick();
}, // This is the compiled code using the official way
//function () {
//_this2.tick();
//}, // This is the compiled code of another working example
1000
);
};
So, I am asking, why must we use the arrow function syntax here? 所以,我问,为什么我们必须在这里使用箭头函数语法? Why the equivalent ways does not get compiled correctly?
为什么等效方法无法正确编译? Is this a bug of React or Babel?
这是React还是Babel的错误?
EDIT: 编辑:
OK. 好。 Thank you very much, guys!
非常感谢你们! That tricky thing about "this" in Javascript almost answers every question I have.
Javascript中关于“ this”的棘手问题几乎可以回答我的每个问题。 Now I know there is a big difference between
() => {}
definition and function () {}
definition, and why Babel doesn't do what I expect. 现在,我知道
() => {}
定义和function () {}
定义之间有很大的区别,以及为什么Babel不按照我的期望做。
But, this does not answer why this could not work 但是,这不能回答为什么这行不通
this.timerID = setInterval(
this.tick, // This cannot work in CodePen
1000
);
Could someone also take a look on this "easy" line of code? 有人还能看看这行“简单”的代码吗? I guess it's not related to "this" in the same way?
我猜它与“ this”不一样吗?
Function () {} and () =>{} are NOT the same thing. 函数(){}和()=> {}是不一样的东西。
Consider: 考虑:
#1
function foo() {
console.log('foo');
}
vs:
#2
foo = () => {
console.log('foo')
}
Function #1 has a newly created context confined to the function, whereas function #2 doesn't create a new context this
variable. 函数1具有一个新创建的上下文,该上下文仅限于该函数,而函数2没有
this
变量创建新的上下文。
When Babel converts everything, I believe in order for function #2 to not have a new context it does something like this: 当Babel转换所有内容时,我相信为了让函数#2没有新的上下文,它会执行以下操作:
foo = () => {
console.log(this.data);
}
Becomes 成为
var this_2 = this;
function foo () {
console.log(this_2.data);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.