我是React的新手。我在遵循React官方页面https://facebook.github.io/react/docs/state-and-lifecycle.html的“快速入门”时遇到了一个奇怪的问题。您可以在此处尝试使用CodePen:http://codepen.io/gaearon/pen/amqdNA?editors=0010
在此代码段中
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
它使用箭头函数语法定义一个将重复执行的函数,方法是将匿名函数对象作为setInterval()
的第一个参数传递。
由于我是一个好奇的家伙,我尝试了几种不同的方法来传递“等效”函数对象作为第一个参数。但是我的方式都没有用。
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
);
}
我认为在纯Javascript代码段中,所有这些方式都适用于setInterval
。特别是,正如官方文档(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions)所说,箭头函数定义通常等同于function () { ... }
定义。但它们似乎在React和Babel中并不相同。
在我通过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
);
};
所以,我问,为什么我们必须在这里使用箭头函数语法?为什么等效方法无法正确编译?这是React还是Babel的错误?
编辑:
行。非常感谢你们! Javascript 几乎中关于“this”的那个棘手的事情回答了我的每一个问题。现在我知道() => {}
定义和function () {}
定义之间存在很大差异,为什么Babel没有按照我的预期行事。
但是,这并没有回答为什么这不起作用
this.timerID = setInterval(
this.tick, // This cannot work in CodePen
1000
);
有人也可以看看这个“简单”的代码行吗?我想这与“这个”的方式无关吗?
答案 0 :(得分:1)
函数(){}和()=> {} NOT 是同一件事。
考虑一下:
#1
function foo() {
console.log('foo');
}
vs:
#2
foo = () => {
console.log('foo')
}
函数#1将新创建的上下文限制在函数中,而函数#2不创建新的上下文this
变量。
当Babel转换所有东西时,我相信为了让函数#2没有新的上下文它会做这样的事情:
foo = () => {
console.log(this.data);
}
<强>变为强>
var this_2 = this;
function foo () {
console.log(this_2.data);
}