js中继承方式

目录

1.原型链继承

2.构造函数继承

3.组合继承

前三种继承方式图解

4.原型式继承

5.寄生式继承

6.寄生组合式继承

寄生组合式继承

后三种图解

 总结

1.原型链继承

 // 父类
        function Father(name){
            this.name = name;
            this.sayName = function(){
                console.log(this.name)
            }
        }
        Father.prototype.age = 10;
     
        function Son(){
            this.sonname = "jack"
        }

        Son.prototype = new Father();//原型链继承

        var son1 = new Son()
        var son2 = new Son()

重点:让子实例对象指向父实例对象,使其可以访问父的原型对象

缺点:1.所有子实例对象公用一个原型对象。如果有一个改变则全部跟着改变

           2.子实例对象无法向父实例对象传参

2.构造函数继承

 function Parent1(name){//0x1111
            // console.log(this)
            this.name = name
        }
        Parent1.prototype.getName = function(){
            return this.name;
        }
        
        function Child1(name){
            Parent1.call(this,name)
            this.type = "child1"
        }
        var child1 = new Child1("qwe")
        var child2 = new Child1("abc")
        console.log(child1)
        console.log(child2)
        child.getName()

重点:通过this指向来改变,使其能够访问构造函数

特点: 1只继承父类构造函数的成员,没有继承父类原型的成员

            2解决原型链继承的缺点

            3可以继承多个构造函数的属性(call多个)

            4.子实例可以向父实例传参

 缺点:1.只继承父类构造函数的成员,没有继承父类原型的成员

            2.无法实现构造函数的复用(每次用每次改变父构造函数的this指向)

            3.每个新实例都有父类构造函数的副本造成内存臃肿

3.组合继承

function Father(name){
            this.name = name;
        }
        Father.prototype.aaa = function(aaa){
            console.log(aaa)
        }
        function Son(name){
            Father.call(this,name)
            this.type = "son"
        }
        Son.prototype = new Father();
        var s = new Son("jack")
        console.log(s)
        s.aaa("aaa的参数")

核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

缺点:每个新实例都有父类构造函数的副本造成内存臃肿

前三种继承方式图解

4.原型式继承

ES5 里面的 Object.create 方法,这个方法接收两个参数:一是用作新对象原型的对象、二是为新对象定义额外属性的对象(可选参数)

 var parent4 = {
            name: "parent4",
            friends: ["p1", "p2", "p3"],
            getName: function () {
                return this.name;
            }
        };

        var person4 = Object.create(parent4);
        person4.name = "tom";
        person4.friends.push("jerry");
        var person5 = Object.create(parent4);
        person5.friends.push("lucy");

        console.log(person4.name);//tom
        console.log(person4.name === person4.getName());//true
        console.log(person5.name);//person4
        console.log(person4.friends);//Array
        console.log(person5.friends);//Array

通过 Object.create 这个方法可以实现普通对象的继承,不仅仅能继承属性,同样也可以继承 getName 的方法,Object.create 方法是可以为一些对象实现浅拷贝的。

特定场景:原型式继承非常适合不需要单独创建构造函数

5.寄生式继承

使用原型式继承可以获得一份目标对象的浅拷贝,然后利用这个浅拷贝的能力再进行增强,添加一些方法,这样的继承方式就叫作寄生式继承。寄生式继承相比于原型式继承,还是在父类基础上添加了更多的方法。

<script>
        var parent5 = {
            name: "parent5",
            friends: ["p1", "p2", "p3"],
            getName: function () {
                return this.name;
            }
        };

        function clone(original) {
            var clone = Object.create(original);
            clone.getFriends = function () {
                return this.friends
            };
            return clone;
        }

        var person5 = clone(parent5);
        console.log(person5.getName()); // parent5
        console.log(person5.getFriends()); //  ['p1', 'p2', 'p3']

    </script>

特点:它不仅仅有 getName 的方法,而且可以看到它最后也拥有了 getFriends 的方法。

6.寄生组合式继承

function inheritPrototype(subType, superType) {
    let prototype = Object.create(superType.prototype); // 创建对象
    prototype.constructor = subType; // 增强对象
    subType.prototype = prototype; // 赋值对象
}
 
function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
 
SuperType.prototype.sayName = function() {
    console.log(this.name);
};
 
function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
 
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function() {
    console.log(this.age);
};
 
var subTupe1 = new SubType('name1', 1)
var subTupe2 = new SubType('name2', 2)

重点:基本思路是不通过调用父类构造函数给子类原型赋值,而是取得父类原型的一个副本。

特点:组合继承最大的问题就是无论在什么情况下,都会调用两次构造函数:一次是在创建子类型原型时,另一次是在子类型构造函数内部。

缺点:比较复杂

寄生组合式继承

后三种图解

 总结

     组合继承弥补了原型链和构造函数的不足,是 JavaScript 中使用最多的继承模式。而且组合继承也保留了 instanceof 操作符和 isPrototypeOf()方法识别合成对象的能力,但调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)。

     寄生组合式继承是上面几种中最优的方式,基本可以解决前几种继承方式的缺点,较好地实现了继承想要的结果,同时也减少了构造次数,减少了性能的开销但比较复杂。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值