我目前正在阅读官方的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函数的行为,我希望随后会出现混乱^^
答案 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