面试官:super()和super(props)有什么区别?

一、ES6类

ES6中,通过extends关键字实现类的继承,方式如下:

class sup {
    constructor(name) {
        this.name = name
    }

    printName() {
        console.log(this.name)
    }
}


class sub extends sup{
    constructor(name,age) {
        super(name) // super代表的事父类的构造函数
        this.age = age
    }

    printAge() {
        console.log(this.age)
    }
}

let jack = new sub('jack',20)
jack.printName()    //输出 : jack
jack.printAge()    //输出 : 20

在上面的例子中,可以看到通过super关键字实现调用父类,super代替的是父类的构建函数,使用super(name)相当于调用sup.prototype.constructor.call(this,name)

如果在子类中不使用super,关键字,则会引发报错,如下:

报错的原因是 子类是没有自己的this对象的,它只能继承父类的this对象,然后对其进行加工

super()就是将父类中的this对象继承给子类的,没有super()子类就得不到this对象

如果先调用this,再初始化super(),同样是禁止的行为

class sub extends sup{
    constructor(name,age) {
        this.age = age
        super(name) // super代表的事父类的构造函数
    }
}

所以在子类constructor中,必须先调用super才能引用this

二、类组件

React中,类组件是基于es6的规范实现的,继承React.Component,因此如果用到constructor就必须写super()才初始化this

这时候,在调用super()的时候,我们一般都需要传入props作为参数,如果不传进去,React内部也会将其定义在组件实例中

// React 内部
const instance = new YourComponent(props);
instance.props = props;

所以无论有没有constructor,在renderthis.props都是可以使用的,这是React自动附带的,是可以不写的:

class HelloMessage extends React.Component{
    render (){
        return (
            <div>nice to meet you! {this.props.name}</div>
        );
    }
}

但是也不建议使用super()代替super(props)

因为在React会在类组件构造函数生成实例后再给this.props赋值,所以在不传递propssuper的情况下,调用this.propsundefined,如下情况:

class Button extends React.Component {
  constructor(props) {
    super(); // 没传入 props
    console.log(props);      //  {}
    console.log(this.props); //  undefined
  // ...
}

而传入props的则都能正常访问,确保了 this.props 在构造函数执行完毕之前已被赋值,更符合逻辑,如下:

class Button extends React.Component {
  constructor(props) {
    super(props); // 没传入 props
    console.log(props);      //  {}
    console.log(this.props); //  {}
  // ...
}

三、总结

React中,类组件基于ES6,所以在constructor中必须使用super

在调用super过程,无论是否传入propsReact内部都会将porps赋值给组件实例porps属性中

如果只调用了super(),那么this.propssuper()和构造函数结束之间仍是undefined

参考文献

  • https://overreacted.io/zh-hans/why-do-we-write-super-props/

  • https://segmentfault.com/q/1010000008340434

--The End--

系列正在更新:5/33

点击下方卡片解锁更多

创作不易,星标、点赞、在看 三连支持

下面是设计的抽象类 Employee 和派生类 Manager 和 Saleman 的代码实现: ```c++ #include <iostream> #include <string> using namespace std; // 定义抽象类 Employee class Employee { protected: string id; // 员工号 string name; // 姓名 int age; // 年龄 double salary; // 工资 public: Employee(string _id, string _name, int _age, double _salary) : id(_id), name(_name), age(_age), salary(_salary) {} virtual double pay() = 0; // 纯虚函数 }; // 定义派生类 Manager class Manager : public Employee { private: double fixedSalary; // 固定工资 public: Manager(string _id, string _name, int _age, double _fixedSalary) : Employee(_id, _name, _age, 0), fixedSalary(_fixedSalary) {} double pay() { return fixedSalary; } // 实现 pay 函数 }; // 定义派生类 Saleman class Saleman : public Employee { private: double salesVolume; // 销售量 public: Saleman(string _id, string _name, int _age, double _salesVolume) : Employee(_id, _name, _age, 0), salesVolume(_salesVolume) {} double pay() { return 0.04 * salesVolume; } // 实现 pay 函数 }; int main() { Employee *p; // 声明一个基类指针 Manager A("1001", "Zhang San", 25, 5000); // 创建 Manager 类对象 A Saleman B("1002", "Li Si", 28, 100000); // 创建 Saleman 类对象 B p = &A; // 指针指向对象 A cout << "ID. " << p->id << " Name: " << p->name << " Age: " << p->age << " Salary: " << p->pay() << endl; p = &B; // 指针指向对象 B cout << "ID. " << p->id << " Name: " << p->name << " Age: " << p->age << " Salary: " << p->pay() << endl; return 0; } ``` 程序运行结果: ``` ID. 1001 Name: Zhang San Age: 25 Salary: 5000 ID. 1002 Name: Li Si Age: 28 Salary: 4000 ``` 其中,抽象类 `Employee` 中包含了员工的基本信息和一个纯虚函数 `pay()`,派生类 `Manager` 和 `Saleman` 分别继承了 `Employee` 类,并实现了自己的 `pay()` 函数。在 `main()` 函数中声明了一个 `Employee` 类型的指针 `p`,指向不同的派生类对象,调用不同的 `pay()` 函数,输出不同的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值