ES6之类的方式完成继承

2018-09-05  本文已影响0人  锋享前端

继承

在ES6之前要完成继承,需要写很多的代码。看下面的继承的例子:

<script type="text/javascript">
    function Father(name) {
        this.name = name;
    }
    Father.prototype.sayName = function () {
        console.log(this.name);
    }

    function Son(name,age) {
        Father.call(this, name);
        this.age = age;
    }
    Son.prototype = new Father();
    Son.prototype.constructor = Son;
    Son.prototype.sayAge = function () {
        console.log(this.age);
    }

    var son1 = new Son("儿子", 20);
    son1.sayAge();  //20
    son1.sayName(); //儿子

</script>

1 继承的基本写法

如果在ES6通过类的方式完成继承就简单了很多。

需要用到一个新的关键字:extends

<script type="text/javascript">
    class Father{
        constructor(name){
            this.name = name;
        }
        sayName(){
            console.log(this.name);
        }
    }
    class Son extends Father{  //extents后面跟表示要继承的类型
        constructor(name, age){
            super(name);  //相当于以前的:Father.call(this, name);
            this.age = age;
        }
        //子类独有的方法
        sayAge(){
            console.log(this.age);
        }
    }

    var son1 = new Son("李四", 30);
    son1.sayAge();
    son1.sayName();
    console.log(son1 instanceof Son);  // true
    console.log(son1 instanceof Father);  //true

</script>

这种继承方法,和我们前面提到的构造函数+原型的继承方式本质是一样的。但是写起来更简单,可读性也更好。

关于super的使用,有几点需要注意:

  1. 你只能在派生类中使用 super(),否则(没有使用 extends 的类或函数中使用)一个错误会被抛出。
  2. 你必须在构造函数的起始位置调用 super(),因为它会初始化 this。任何在 super() 之前访问 this 的行为都会造成错误。也即是说super()必须放在构造函数的首行。
  3. 在类构造函数中,唯一能避免调用 super() 的办法是返回一个对象。

2在子类中屏蔽父类的方法(重写)

如果在子类中声明与父类中的同名的方法,则会覆盖父类的方法。(这种情况在其他语言中称之为 方法的覆写、重写 )

<script type="text/javascript">
    class Father{
        constructor(name){
            this.name = name;
        }
        sayName(){
            console.log(this.name);
        }
    }
    class Son extends Father{  //extents后面跟表示要继承的类型
        constructor(name, age){
            super(name);  //相当于以前的:Father.call(this, name);
            this.age = age;
        }
        //子类独有的方法
        sayAge(){
            console.log(this.age);
        }
        //子类中的方法会屏蔽到父类中的同名方法。
        sayName(){
            super.syaName();  //调用被覆盖的父类中的方法。 
            console.log("我是子类的方法,我屏蔽了父类:" + name);
        }
    }

    var son1 = new Son("李四", 30);
    son1.sayAge();
    son1.sayName();
</script>

如果在子类中又确实需要调用父类中被覆盖的方法,可以通过super.方法()来完成。

注意:

  1. 如果是调用构造方法,则super不要加点,而且必须是在子类构造方法的第一行调用父类的构造方法
  2. 普通方法调用需要使用super.父类的方法() 来调用。

3 静态方法也可以继承

<script type="text/javascript">
   class Father{
       static foo(){
           console.log("我是父类的静态方法");
       }
   }
   class Son extends Father{

   }
   Son.foo(); //子类也继承了父类的静态方法。  这种方式调用和直接通过父类名调用时一样的。

</script>
上一篇 下一篇

猜你喜欢

热点阅读