JS 是如何实现继承的

1、原型链

 基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法。

 原型链算是实现继承的一个简单又比较好理解的一个方法了,对于原型链不理解的可以先去看看彻底理解 JS  的原型和原型链。具体实现如下:

<script>
    function Parent(){
        this.a = 66;
        this.arr = [11];
    }
    function Children(){

    }
    Children.prototype = new Parent();//核心

    var child1 = new Children();
    var child2 = new Children();
    console.log(child1.a);//66
    console.log(child2.a);//66
    //修改基本数据类型
    child2.a = 88;
    console.log(child1.a);//66
    console.log(child2.a);//88
    //修改引用类型
    child2.arr.push(22);
    console.log(child1.arr);//[11,22]
    console.log(child2.arr);//[11,22]
</script>

 可以看出用原型链实现继承时,要是有多个对象对同一个属性进行修改,而且这个属性还是引用类型,容易造成全部对象的那个属性都被迫修改了,即子类实例共享父类引用属性。还不可以向父类传参。

 

2、借用构造函数

<script>
    function Parent(){
        this.arr = [11];
        this.fun = function (){
            //...
        }
    }
    function Children(){
        Parent.call(this);//核心
    }
    var child1 = new Children();
    var child2 = new Children();
    console.log(child1.arr);//[11]
    console.log(child2.arr);//[11]
    //只修改child2
    child2.arr.push(66);
    console.log(child1.arr);//[11]
    console.log(child2.arr);//[11,66]
    //函数
    console.log(child1.fun() === child2.fun()); //false
</script>
可以看出解决了子类实例共享父类引用属性的问题,此方法还可以在 call 中向父类进行传参。但是无法实现函数复用,每个子类实例都持有一个新的fun函数,太多了就会影响性能,内存爆炸。

 

3、组合继承

<script>
    function Parent(){
        this.arr = [11];
    }
    //在此处声明函数
    Parent.prototype.fun = function (){};

    function Children(){
        Parent.call(this);//核心
    }

    Children.prototype = new Parent(); //核心

    var child1 = new Children();
    var child2 = new Children();
    console.log(child1.fun() === child2.fun()); //true
</script>

 把实例函数都放在原型对象上,以实现函数复用。同时还要保留借用构造函数方式的优点,通过Super.call(this);继承父类的基本属性和引用属性并保留能传参的优点;通过Sub.prototype = new Super();继承父类函数,实现函数复用。但是子类原型上有一份多余的父类实例属性,因为父类构造函数被调用了两次,生成了两份,而子类实例上的那一份屏蔽了子类原型上的,又是内存浪费,

 

4、使用 ES6 的 class 关键字

<script>
    class Parent{
        constructor(){
            this.a = 66;
            this.b = 'luck';
        }
        method(){
            console.log('我是父类的方法');
        }
    }
    class child extends Parent{
        constructor() {
            super();
        }
        method() {
            super.method();
        }
    }
    const per = new child();
    console.log(per)
    console.log(per.method());
</script>

  

 

posted @ 2021-11-06 10:30  打遍天下吴敌手  阅读(81)  评论(0编辑  收藏  举报