继承

一、.原型链:

基本思想:就是利用原型让一个引用类型继承另一个引用类型的属性与方法;

概念:构造函数、原型、实例的关系:每一个构造函数都有一个原型对象,原型对象内部有一个指向构造函数的指针,实例都包含一个指向原型对象的你内部指针。如果,让一个原型对象等于另一个类型的实例,那么,此时的原型对象将包含指向另一个原型对象的指针,另一个原型对象中也包含这指向另一个构造函数的指针,加入另一个原型又是另一个类型的实例,那以此类推,层层递进,就构成了实例与原型的链条。

var Father = function(x){
            this.name = ['red','blue','green'];
            this.color = 'red';
        }
        Father.prototype.type = '华为';
        Father.prototype.getfathername=function(){
            console.log("我是父亲")
        };
        var Son = function(){
            
        }
        Son.prototype = new Father();
        var father = new Father();

        var son1 = new Son();
        var son2=  new Son();
        father.getfathername();
        son1.getfathername();   
        son1.name.push('black');
        son1.color = 'black';
        console.log(son1.name , son2.name);     //['red','blue','green','black'] , ['red','blue','green','black']
        console.log(son1.color , son2.color);   //'black  red   

弊端:

1.来自引用类型值的原型,通过原型实现继承时,原型实际上会变成另一个 类型的实例。于是,原先的实例属性也就顺理成章的变成了现在的原型属性了。

构造函数Father有一个属性,father的每一个实例都会有这个属性,Son用过原型 继承了Father之后,Son.prototype就变成了Father的一个实例,Son的所有实例也都 共享这个属

Color(基本类型值):上述例子中son1color值变了之后,son2color值没有变化, 这是因为,当实例中存在与原型对象上同名的属性时,会自动屏蔽原型对象上的同 名属性,son1.color=‘black’,只是给son1添加一个本地属color,并设置了相关值,所 以打印son1.color时,实际打印的是son1的本地属性,而不是其原型对象上的属性 (和本地属性同名,已经被屏蔽了)。

Name(引用类型值):son1name值变了之后,son2name值也变化了。

以:原型上任何类型的属性值都不会通过实例被重写,但是引用类型的属性值会 通过实例的影响而修改;

2.在创建子类的实例的时候,不能向父类的构造函数中传参数

二、借用构造函数

(为解决原型继承带来的问题,继而用借用构造函数)

基本思想:在子类构造函数的内部调用父类构造函数。可以使用apply()和call()在 新创建的对象上执行构造函数;

var Father = function(x){
            this.name = ['red','blue','green'];
            this.color = 'red';
        }
        Father.prototype.type = '华为';
        Father.prototype.getfathername=function(){
            console.log("我是父亲")
        };
        var Son = function(){
            //通过call(),调用了Father
            Father.call(this,'向父类传的x参数');
        }
        var father = new Father();

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

        son1.name.push('black');
        son1.color = 'black';
        console.log(son1.name , son2.name);     //['red','blue','green','black'] , ['red','blue','green']
        console.log(son1.color , son2.color);   //'black  red    

优点:(1)通过使用call和apply方法,实际上是在新创建的Son实例环境下调用了Father构造函数,这样,就会在新Son对象上之心Father()函数中定义的所有对象初始化代码,所以,Son的每个实例都会有自己的name、color属性了;

(2)相对于原型链老说,借用构造函数可以在子类构造函数中向父类构造函数传递参数

弊端:方法都在构造函数中定义,因为函数复用就无从谈起。而且。在父类原型中定义的方法,对子类是不可见的。

三、组合继承

基本思想:把原型链继承与借用构造函数结合到一块,使用原型链实现对构造函数的原型上的属性和方法的继承,借用构造函数实现对实例属性的继承,这样,既通过在原型上定义方法实现了函数复用,又保障每个实例都有他自己的属性。

var Father = function(x){
            this.name = ['red','blue','green'];
            this.color = 'red';
        }
        Father.prototype.type = '华为';
        Father.prototype.getfathername=function(){
            console.log("我是父亲")
        };
        var Son = function(){
            //通过call(),调用了Father
            Father.call(this,'向父类传的x参数');
        }
        var father = new Father();
        Son.prototype = new Father();
        var son1 = new Son();
        var son2=  new Son();
        
        son1.name.push('black');
        son1.color = 'black';
        console.log(son1.name , son2.name);     //['red','blue','green','black'] , ['red','blue','green']
        console.log(son1.color , son2.color);   //'black  red    

四、通过中转函数,避免二次实例化属性

var Father = function(x){
            this.name = ['red','blue','green'];
            this.color = 'red';
        }
        Father.prototype.type = '华为';
        Father.prototype.getfathername=function(){
            console.log("我是父亲")
        };
        var Son = function(){
            //通过call(),调用了Father
            Father.call(this,'向父类传的x参数');
        }
        var father = new Father();
        Son.prototype = Object.create(Father.prototype);
        var son1 = new Son();
        var son2=  new Son();

        son1.name.push('black');
        son1.color = 'black';
        son1.getfathername();
        console.log(son1.name , son2.name);     //['red','blue','green','black'] , ['red','blue','green']
        console.log(son1.color , son2.color);   //'black  red    

 

 

转载于:https://my.oschina.net/u/3950671/blog/2875679

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值