现在有一个自定义对象Animal,

    function Animal(name) {        this.name=name    }    Animal.prototype.getName=function () {        console.log(this.name);    }

想让对象Dog来继承Animal的所有属性和方法,常用的继承方式有:

1.组合继承

        function Dog(name, color) {            //继承父类的实例属性            Animal.call(this, name);//显示绑定this            this.color = color;        }        //继承父类构造函数原型属性的方法 重写原型对象        Dog.prototype = new Animal();        Dog.prototype.constructor = Dog;        var d1 = new Dog('小白');        var d2 = new Dog('小黑');        console.log(d1.name, d2.name)        d1.getName();        d2.getName()

首先在Dog构造函数内部,通过强制改变Animal构造函数的this,实现继承Animal构造函数内部属性的目的,然后通过改变原型对象,继承Animal原型对象上的共享属性和方法。
但是这种方式有一个缺点,就是Animal函数执行了两次。

2.寄生组合式继承

寄生组合继承被称为最友好,最完美的继承方案。

    function Dog(name) {        //继承父类的实例属性        Animal.call(this,name);    }    //通过Object的create方法,创建一个以Animal.prototype为原型对象的实例对象,赋值给Dog.prototype     Dog.prototype=Object.create(Animal.prototype);     Dog.prototype.constructor=Dog;

3.js中怎么实现多重继承呢?

js本身是没有多重继承的概念的,但是我们可以通过一些方法实现多重继承的效果。
现在有两个构造函数A,B

    function A() {        this.type = 'A'    }    A.prototype.getType=function () {        console.log(this.type);    }    function B() {        this.name = 'B'    }    B.prototype.getName=function () {        console.log(this.name);    }

A,B毫无关联,但是我们想让C同时继承A与B的方法,可以先让C继承A,再将B上面的属性和方法复制到C上。

    //寄生组合模式    function C() {        //继承A的属性 借用构造函数        A.call(this);      }    //继承A上的共享方法    C.prototype=Object.create(A.prototype);    C.prototype.constructor=C;

然后可以通过构造函数的方法,继承B的属性B.call(this),再将B.prototype的属性和方法复制到C.prototype上即可,可以通过Object.assign实现复制功能,Object.assign(C.prototype,B.prototype);
最终可以写为:

    function C() {        //继承A与B的属性 借用构造函数        A.call(this);        B.call(this);    }    //继承A上的共享方法    C.prototype=Object.create(A.prototype);    C.prototype.constructor=C;    //将B的原型属性上的方法 复制到C的原型属性上     Object.assign(C.prototype,B.prototype);

4.ES6中的继承

es6中引入了类的概念,在创建类时,可以使用class关键字,继承类时,可以使用extends关键字。

 class Dog {            constructor(name, age = 2) {                this.name = name;                this.age = age;            };//分号            //类的方法 除了constructor 都定义在了类的prototype上            getName() {                return this.name;            };            //静态方法 静态方法不会被实例继承 通过类直接调用            static foo() {                console.log(111111111);            }        }

类中声明的全部是函数。
constructor函数中,定制实例对象的属性或方法,相当于构造函数的角色,getName函数是共用的方法,相当于定义在了原型对象上。

        let d = new Dog("dog", 5);        // 通过构造函数调用静态方法        Dog.foo();        console.log(d.getName());

ES6的继承机制:先创建父类实例对象,再创建子类实例对象 然后修改父类的this,将其指向子类实例对象。子类是没有this的,是继承的父类的this。所以在继承时必须通过super方法继承父类的属性。

    class Tidy extends Dog {            constructor(name, age, color) {                super(name, age);//super调用父元素的方法 必须调用super 不然得不到this                 this.color = color;            };            //子类自己的方法            getColor() {                console.log(this.color);            }            //重写父类的方法            getName() {                return this.name + super.getName();                //super相当于父类构造函数的原型属性 在此处相当于 class Dog            }        }

Tidy类通过extends继承了Dog类。

  let tidy = new Tidy("tidy", 2, "red");        tidy.getColor();        console.log(tidy.getName());