我可以在反应组件的构造函数中使用箭头函数吗?

时间:2017-04-25 03:15:16

标签: javascript reactjs constructor ecmascript-6 arrow-functions

这个问题与When using React Is it preferable to use fat arrow functions or bind functions in constructor?类似,但有点不同。您可以在构造函数中将函数绑定到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 = () => {};
  }
}

这两种方式的优点和缺点是什么?感谢。

4 个答案:

答案 0 :(得分:10)

出于某些原因,选项1通常更为可取。

class Test extends React.Component{
  constructor(props) {
    super(props);

    this.doSomeThing = this.doSomeThing.bind(this);
  }

  doSomething() {}
}

原型方法更加清晰。子类可以使用

覆盖或扩展doSomething
doSomething() {
  super.doSomething();
  ...
}

当实例属性

this.doSomeThing = () => {};

或ES.next类字段

doSomeThing = () => {}
而使用

,调用super.doSomething()是不可能的,因为该方法未在原型上定义。覆盖它将导致在父和子构造函数中分配this.doSomeThing属性两次。

mixin技术也可以使用原型方法:

class Foo extends Bar {...}
Foo.prototype.doSomething = Test.prototype.doSomething;

原型方法更容易测试。在类实例化之前,它们可以被窥探,存根或模拟:

spyOn(Foo.prototype, 'doSomething').and.callThrough();

这允许在某些情况下避免竞争条件。

答案 1 :(得分:3)

我想你可能想要这样。你的第一种情况也是如此。 它将在第2阶段与babel一起工作。 (transform-class-properties: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 = () => {}
}




答案 2 :(得分:3)

方法1对我来说更具可读性,更具惯用性。

此外,在类中声明方法而不是构造函数,可以共享方法。

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%。

答案 3 :(得分:1)

检查出来:

https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&targets=&browsers=&builtIns=false&debug=false&code=class%20Dog%20%7B%0A%20%20constructor()%20%7B%0A%20%20%20%20%0A%20%20%20%20this.cat%20%3D%20_%3D%3E%20%7B%0A%20%20%20%20%20%20this%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D

我们可以看到babel transiles

this.doSomeThing = () => { this };

var _this = this;
this.doSomething = function() { _this }

编辑:我稍微误读了你的帖子,但上面的内容仍然是真实有趣的。 @CodinCat指出了重要的事情:在构造函数中声明一个函数意味着在创建对象时将该函数添加到对象需要花费时间(尽管很少),并且也可能占用内存,因为该类的实例不共享同样的doSomeThing方法。

edit2:绑定(this)到函数实际上导致我上面列出的确切问题。换句话说,这两种方法几乎完全相同。