Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
huihuiha opened this issue Jul 5, 2021 · 5 comments
Open

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

huihuiha opened this issue Jul 5, 2021 · 5 comments

Comments

@huihuiha
Copy link
Contributor

huihuiha commented Jul 5, 2021

一、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

参考文献

@a12asdf
Copy link

a12asdf commented Aug 6, 2021

_aSDasdf_****

@a12asdf
Copy link

a12asdf commented Aug 6, 2021

12

  • 2

  • 2

@2714836845
Copy link

说的有点问题,

@2714836845
Copy link

不管调不调用super()this还是可以指向当前对象,只是调用super,可以继承父类属性,之所以报错是因为预防调试出错。

@2714836845
Copy link

父组件的属性作为他原型对象上的属性,当自己属性上不存在时,才会去原型上找,实际上this不管super不super都是指向当前对象

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants