JS实现继承的几种方式

134 阅读1分钟

JS实现继承的几种方式

原型链继承

 function A(name,age){
            this.name =name;
            this.age =age;
            this.happy=['跳舞','篮球','喝酒']
        }
        A.prototype.say=function(){
            console.log('我是'+this.name+'我喜欢'+this.happy);
        }
        function B(){

        }
        B.prototype =new A('zf',18);
        let Bb =new B();
        console.log(Bb.name,Bb.age);
        Bb.say();

结果

8b566c5e472495753d2f0df6d2e48e6.png

原型链继承的问题:属性以堆的形式存在的,都发生变化,基础类型类型不发生变化。

         let Ba =new B();
         let Bb =new B();
         Bb.happy.push('唱歌');
         Bb.name='李四';
         console.log(Ba.name,Bb.name);
         console.log(Ba.happy,Bb.happy);

Bb的name发生改变,Ba的name没有改变, Bb数组里添加了值,Ba一起改变。 7ed72f65db23349a05a8a85924e431c.png

构造函数继承

function A(name,age){
            this.name =name;
            this.age =age;
            this.happy=['跳舞','篮球','喝酒']
        }
        A.prototype.say=function(){
            console.log('我是'+this.name+'我喜欢'+this.happy);
        }
        function B(name,age){
            A.call(this,name,age)
        }
        let Ba =new B('zf' ,18);
        let Bb =new B('zff',188);
        console.log(Ba.name,Ba.age);
        console.log(Bb.name,Bb.age);    
        Bb.happy.pop();
        console.log(Ba);
        console.log(Bb);

结果: 构造函数使父类的引用属性不会被共享,但是只能继承父类的实例属性和方法,不能继承原型的属性或者方法。 385132bbad80c01d8617604cc893c6b.png

组合继承

结合原型链继承和构造函数继承

        function A(name,age){
            this.name =name;
            this.age =age;
            this.happy=['跳舞','篮球','喝酒']
        }
        A.prototype.say=function(){
            console.log('我是'+this.name+'我喜欢'+this.happy);
        }
        function B(name,age){
            A.call(this,name,age)
        }
        B.prototype =new A();
        let Ba =new B('zf' ,18);
        let Bb =new B('zff',188);
        console.log(Ba.name,Ba.age);
        console.log(Bb.name,Bb.age);    
        Bb.happy.pop();
        console.log(Ba);
        console.log(Bb);

结果: 即继承了属性和方法,也继承了原型的属性和方法 缺点:性能不好,实例化过多

00df6f4d071ad62a106dd1bc63af76b.png

寄生组合继承

不再实例化A ,创建一个新的对象,指向A的prototype

        function A(name,age){
            this.name =name;
            this.age =age;
            this.happy=['跳舞','篮球','喝酒']
        }
        A.prototype.say=function(){
            console.log('我是'+this.name+'我喜欢'+this.happy);
        }
        function B(name,age){
            A.call(this,name,age);
        }
        B.prototype=Object.create(A.prototype);
        let Ba =new B('zf' ,18);
        let Bb =new B('zff',188);
        console.log(Ba.name,Ba.age);
        console.log(Bb.name,Bb.age);    
        Bb.happy.pop();
        console.log(Ba);
        console.log(Bb);

结果:

0e9a628a2154ed3a77336c14523a16d.png