javascript类的“ super”中的参数如何工作?

时间:2018-08-16 08:02:49

标签: javascript reactjs

我目前正在阅读官方的reactJS教程: https://reactjs.org/tutorial/tutorial.html 尽管我并不是javascript的新手,但我在许多方面仍然缺乏经验,对于javascript的OOP部分来说尤其如此。

我最近才刚刚了解super的基本原理。在此处查看官方API https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/super 和这里: https://developer.mozilla.org/de/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

我了解到super调用父类的构造函数。 因此,当我扩展一个类时,可以使用super()定义要输入到父类的构造函数中的内容。

现在,看一下https://developer.mozilla.org/de/docs/Web/JavaScript/Inheritance_and_the_prototype_chain中的示例:

"use strict";

class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

class Square extends Polygon {
  constructor(sideLength) {
    super(sideLength, sideLength);
  }
  get area() {
    return this.height * this.width;
  }
  set sideLength(newLength) {
    this.height = newLength;
    this.width = newLength;
  }
}

var square = new Square(2);

square类具有一个构造函数,该构造函数将其输入放入父类的构造函数的两个参数中。对我来说,这似乎非常好,因为super()会考虑父类构造函数的所有参数。

但是,当我从reactJS教程中查看此示例时,我有点困惑:

class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null,
    };
  }

  render() {
    return (
      <button
        className="square"
        onClick={() => this.setState({value: 'X'})}
      >
        {this.state.value}
      </button>
    );
  }
}

在这里,调用Component类的构造函数,并将参数“ props”插入其中。但是,由于我不了解“ vanilla”组件类的构造函数,因此我想知道这实际上如何工作?好的,也许组件类的构造函数没有“默认”参数,那就可以了。但是,如果不是这种情况,构造函数如何知道如何处理此新参数?是“覆盖”第一个或第二个已经存在的参数,还是只是将新参数添加到现有参数列表中。

并假设默认情况下组件类的构造函数为“空”。当我开始扩展此类并已经添加时,在其构造函数中说三个参数,它如何知道如何处理第四或第五个参数,依此类推? 查看常见的javascript函数的行为,我希望随后会出现混乱^^

1 个答案:

答案 0 :(得分:1)

在ReactJS教程提供的示例中,Square扩展了Component。

在创建新的React组件时,并不一定要重写构造函数,但是如果这样做,则必须调用super(props),因为否则将无法正确初始化基本Component类(在这种情况下,该组件不会在它第一次渲染之前接收传递给它的道具,这将是不好的)。

您自己不会通过调用new MyComponent(props)来实例化React组件,但是React在调用React.createElement或使用jsx <MyComponent {...props} />时会做到这一点。

更一般而言,如果要扩展类,则必须了解要扩展的类,其中包括构造函数所需的参数。

如果要覆盖类的构造函数,则必须遵守该类文档的约定。这包括调用基本构造函数。如果基本构造函数执行了某些操作,则必须通过显式调用它来维持其功能。

通常,覆盖方法也是如此:如果要保留方法的初始功能,则应在覆盖版本中调用它

anOverridenMethod(...arguments) {
    doSomethingBefore();
    super.anOverridenMethod(...arguments);
    doSomethingAfter();
}

但是实际上,在React中,大多数可重写方法(componentWillReceiveProps,shouldComponentUpdate ...)根本没有实现,因此您无需费心调用基本方法。因此,super的最常见用例是在构造函数中。

也就是说,在React中,组合优先于继承(React组件并不是真的要扩展)

See this ressource discuting the difference between the two concepts