首页 > 解决方案 > javascript 类的“super”中的参数究竟是如何工作的?

问题描述

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

我只是最近超级基本上是如何工作的。在这里查看官方 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 函数的行为,我预计会出现混乱 ^^

标签: javascriptreactjs

解决方案


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

当创建一个新的 React 组件时,重写构造函数不是强制性的,但是如果你这样做了,你必须调用super(props),因为否则基础 Component 类将不会被正确初始化(在这种情况下,组件不会在它之前收到传递给它的 props第一次渲染会很糟糕)。

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

更一般地说,如果您扩展一个类,您必须了解您正在扩展的类,其中包括构造函数所需的参数。

如果要覆盖类的构造函数,则必须遵守类文档的约定。这包括调用基本构造函数。如果基本构造函数做了某事,您必须通过显式调用它来维护它所做的事情。

通常,被覆盖的方法也是如此:如果你想保留一个方法的初始功能,你应该在被覆盖的版本中调用它

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

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

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

请参阅此资源,讨论这两个概念之间的区别


推荐阅读