我可以在反应组件的构造函数中使用箭头函数吗?
Can I use arrow function in constructor of a react component?
这个问题与类似,但有一点不同。您可以在构造函数中将函数绑定到 this
,或者只在构造函数中应用箭头函数。请注意,我的项目中只能使用 ES6 语法。
1.
class Test extends React.Component{
constructor(props) {
super(props);
this.doSomeThing = this.doSomeThing.bind(this);
}
doSomething() {}
}
2.
class Test extends React.Component{
constructor(props) {
super(props);
this.doSomeThing = () => {};
}
}
这两种方式的优缺点是什么?谢谢
我想你可能想要这样。你的第一种情况也是一样的。
它将在第 2 阶段与 babel 一起工作。 (转换-class-属性:http://babeljs.io/docs/plugins/transform-class-properties/)
(预设阶段 2:http://babeljs.io/docs/plugins/preset-stage-2/)
class Test extends React.Component{
constructor(props) {
super(props);
}
doSomeThing = () => {}
}
看看这个:
我们可以看到 babel transpiles
this.doSomeThing = () => { this };
进入
var _this = this;
this.doSomething = function() { _this }
编辑:我稍微看错了你的post,但上面的内容仍然真实有趣。 @CodinCat 指出了重要的事情:在构造函数中声明一个函数意味着在创建对象时需要时间(尽管很少)将该函数添加到对象中,并且还可能占用内存,因为 class 不共享相同的 doSomeThing 方法。
edit2:将 (this) 绑定到函数实际上会导致我上面列出的确切问题。也就是说这两种方法几乎完全一样。
方法 1 对我来说更易读,也更惯用。
此外,在class而不是构造函数中声明方法,方法可以共享。
class Foo {
test() {}
}
const f1 = new Foo()
const f2 = new Foo()
f1.test === f2.test // true
在方法 2 中,您将在每次创建新实例时声明所有方法:
class Foo {
constructor() {
this.test = () => {}
}
}
const f1 = new Foo()
const f2 = new Foo()
// the method is not shareable
f1.test === f2.test // false
理论上方法2速度较慢,但对性能的影响应该可以忽略不计。
我只选择方法 1,因为它在 React documentation 中使用,而且我从未见过有人使用方法 2。
我只是 运行 一些样本来测试性能。在最新的 Chrome (Mac) 中,在构造函数中声明方法比在构造函数中使用 bind
慢大约 90%。
出于某些原因,选项 1 通常更可取。
class Test extends React.Component{
constructor(props) {
super(props);
this.doSomeThing = this.doSomeThing.bind(this);
}
doSomething() {}
}
原型方法更易于扩展。 Child class 可以用
覆盖或扩展 doSomething
doSomething() {
super.doSomething();
...
}
当实例属性
this.doSomeThing = () => {};
或ES.nextclass字段
doSomeThing = () => {}
被使用,调用 super.doSomething()
是不可能的,因为该方法没有在原型上定义。覆盖它将导致在 parent 和 child 构造函数中分配 this.doSomeThing
属性 两次。
混合技术也可以使用原型方法:
class Foo extends Bar {...}
Foo.prototype.doSomething = Test.prototype.doSomething;
原型方法更容易测试。它们可以在 class 实例化之前被监视、存根或模拟:
spyOn(Foo.prototype, 'doSomething').and.callThrough();
这可以在某些情况下避免竞争条件。
这个问题与this
,或者只在构造函数中应用箭头函数。请注意,我的项目中只能使用 ES6 语法。
1.
class Test extends React.Component{
constructor(props) {
super(props);
this.doSomeThing = this.doSomeThing.bind(this);
}
doSomething() {}
}
2.
class Test extends React.Component{
constructor(props) {
super(props);
this.doSomeThing = () => {};
}
}
这两种方式的优缺点是什么?谢谢
我想你可能想要这样。你的第一种情况也是一样的。 它将在第 2 阶段与 babel 一起工作。 (转换-class-属性:http://babeljs.io/docs/plugins/transform-class-properties/) (预设阶段 2:http://babeljs.io/docs/plugins/preset-stage-2/)
class Test extends React.Component{
constructor(props) {
super(props);
}
doSomeThing = () => {}
}
看看这个:
我们可以看到 babel transpiles
this.doSomeThing = () => { this };
进入
var _this = this;
this.doSomething = function() { _this }
编辑:我稍微看错了你的post,但上面的内容仍然真实有趣。 @CodinCat 指出了重要的事情:在构造函数中声明一个函数意味着在创建对象时需要时间(尽管很少)将该函数添加到对象中,并且还可能占用内存,因为 class 不共享相同的 doSomeThing 方法。
edit2:将 (this) 绑定到函数实际上会导致我上面列出的确切问题。也就是说这两种方法几乎完全一样。
方法 1 对我来说更易读,也更惯用。
此外,在class而不是构造函数中声明方法,方法可以共享。
class Foo {
test() {}
}
const f1 = new Foo()
const f2 = new Foo()
f1.test === f2.test // true
在方法 2 中,您将在每次创建新实例时声明所有方法:
class Foo {
constructor() {
this.test = () => {}
}
}
const f1 = new Foo()
const f2 = new Foo()
// the method is not shareable
f1.test === f2.test // false
理论上方法2速度较慢,但对性能的影响应该可以忽略不计。
我只选择方法 1,因为它在 React documentation 中使用,而且我从未见过有人使用方法 2。
我只是 运行 一些样本来测试性能。在最新的 Chrome (Mac) 中,在构造函数中声明方法比在构造函数中使用 bind
慢大约 90%。
出于某些原因,选项 1 通常更可取。
class Test extends React.Component{
constructor(props) {
super(props);
this.doSomeThing = this.doSomeThing.bind(this);
}
doSomething() {}
}
原型方法更易于扩展。 Child class 可以用
覆盖或扩展doSomething
doSomething() {
super.doSomething();
...
}
当实例属性
this.doSomeThing = () => {};
或ES.nextclass字段
doSomeThing = () => {}
被使用,调用 super.doSomething()
是不可能的,因为该方法没有在原型上定义。覆盖它将导致在 parent 和 child 构造函数中分配 this.doSomeThing
属性 两次。
混合技术也可以使用原型方法:
class Foo extends Bar {...}
Foo.prototype.doSomething = Test.prototype.doSomething;
原型方法更容易测试。它们可以在 class 实例化之前被监视、存根或模拟:
spyOn(Foo.prototype, 'doSomething').and.callThrough();
这可以在某些情况下避免竞争条件。