网站首页 » 前端开发 » JavaScript » ES6 中的 super 关键字
上一篇:
下一篇:

ES6 中的 super 关键字

前言

关于 ES6 中的 super 关键字估计大家跟我一样还见得比较少,不过没关键,在文我们就来初探下 super 关键字。

super 关键字

在讲 super 关键字之前,我们先来看一段超简单的代码:

class parent{
    constructor(){}
}

class children extends parent{
    constructor(){}
}

其实在上面什么都没有做的类中的 constructor 构造方法我们也可以不写,因为类中如果没有显式地定义构造函数的话,constructor 会自动添加到类中。

但是如果我们在类中使用到 this 的话,我们就必需显式地声明构造函数,并且在构造函数中调用 super() 方法,否则会报错,因为子类是没有自己的 this 对象的。

ES6 跟 ES5 在类的继承的原理上有点不同,ES5 中我们是先创建子类实类,然后再通过型如:Parent.apply(this) 的方式把父类中的方法添加到子类上。而在 ES6 中就正好反过来,先创建父类实例,然后再通过子类的构造函数来修改 this 指向。

class parent{
    constructor(name,hobby){
        this.name = name;
        this.hobby = hobby;
    }
}

class children extends parent{
    constructor(name,hobby,age){
        this.age = age; // 这个会报错
        super(name,hobby);
        this.age = age; // 这个不会,能正常运行
    }
}

const c = new children("小明","篮球");

运行代码我们可以看到在运行到 super(name,hobby) 之前的一行 this.age = age; 会报一个错:

Error

Uncaught ReferenceError: Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor at new children

总结一下,就是只要你继承了父类,那么你就必需在子类的构造函数中调用 super() 方法。关于 super() 方法的介绍现在才刚刚开始。

super 可以当作函数使用,也可以当作对象使用,在这两种情况下,它的用法完全不同,下面我们就来看看它们俩的异同。

super 作为函数

代表父类的构造函数,但返回的是子类,即 super 内部的 this 指向的是子类。当然,通过 new 创建子类的实例时,this 就是指向子类的实例了。

class parent{
    constructor(){
        console.log(this);
    }
}

class children extends parent{
    constructor(){
        super();
    }
}

const c = new children();

注意,super 关键字作为函数时,只能用在子类的构造函数中,用在其它地方就会报错了。

super 作为对象

super 作为对象时,指向父类的原型对象,但在静态方法中指向父类。我们不妨看看下面两个例子

class parent{
    constructor(){}
    say(){
        console.log('hi!');
    }
}

class children extends parent{
    constructor(){
        super();
        super.say();
    }
}

const c = new children();

在子类中可以调用父类的方法,而父类的方法是挂在原型对象上的。不过,这里需要注意的是,定义在父类实例上的属性或方法,super 对象是无法调用的。因为 super 对象指向的是父类的原型对象。

而当 super 作为静态方法的对象使用时,super 将指向父类,而不是父类的原型对象。

class parent{
    constructor(){}
    static say(){
        console.log('parent','static');
    }
    say(){
        console.log('parent','instance');
    }
}

class children extends parent{
    constructor(){
        super();
    }
    static say(){
        super.say(); // 调用父类的静态方法
    }
    say(){
        super.say();
    }
}

children.say(); // parent static
var c = new children();
c.say(); // parent instance

一个小小的 super 关键字竟然隐藏了这多么的知识点,真是深藏不露呀,但对于 super 来说,我们也很容易把它的一些特性记住。只要在理解的情况下,多看两遍,肯定会把 super 搞得服服贴贴,任由你摆弄。

 

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/es6-super/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END