继承、“圣杯模式“

继承、“圣杯模式”

一、为啥继承

大概的思路就是某一个对象(Child)要能够继承来自于另一个对象(Parent)的属性和方法。

二、继承的几种方法

1. 借用构造函数
    function Person(name,age,sex){
         this.name = name;
         this.age = age;
         this.sex = sex;
     }
     function Student(name,age,sex,grade){
         Person.call(this,name,age,sex);
         this.grade = grade;
     }
    var student = new Student();

具体是使用 call/apply,实现借用别人的方法来实现自己的功能
不能继承借用构造函数的原型,每次构造函数都要多走一个函数

2. 传统形式——原型链

将 Child 的 prototype 指向一个 Parent 的实例,实现继承,Child.prototype = new Parent(),这样做之后, Child.prototype 上的属性会被 Parent 实例上的属性覆盖,Child.prototype 上原本的constructor 属性也一样,这时候会变成 Child.prototype.constructor = Parent,

因此,要特别注意,改变 Child.prototype 之后,要手动把他的指向归位 Child.prototype.constructor = Child

一层一层继承下来之后,过多地继承了没用的属性

    Grand.prototype.lastName = '张三';
    function Grand(){ }
    var grand = new Geand();
    Father.prototype = grand;
    function Father(){
        this.name = '王五';
    }
    var father = new Father();
    Son.prototype = father;
    function Son(){
        this.hobbit = '赵六';
    }
    var son = new Son()
3. 共享原型

在第二种方式上改进,直接继承 prototype,让两个构造函数的原型都指向同一个,因为原型地址相同,不能随便改动自己的原型,无法实现某一个的特殊功能,由此在此基础上引出了最完美的圣杯模式

	Father.prototype.lastName = '张三';
    function Father(){
    }
    function Son(){
    }
    Son.prototype = Father.prototype;
    var son = new Son();
    var father = new Father();

在这里插入图片描述

4. 圣杯模式

圣杯模式的出现和思路与浅层克隆和深层克隆问题很相似,都是引入了一个中间的媒介,利用空对象作为中介,空对象几乎不占内存,让空对象的原型指向父亲的原型,让儿子的原型不是直接指向父亲,而是指向空对象的实例,这样也能继承到父亲上的属性,改变时又不会互相影响,最后记得将儿子的构造器归位就可以

	function inherit(Child, Parent){
		function F(){}
		F.prototype = Parent.prototype
		Child.prototype = new F()
        Child.prototype.constructor = Child
	}

关系图变成了如下,红箭头表示人为地引用使地址相同,蓝箭头表示原型链上的继承关系。把红箭头看成是等于号会更好理解一点😅,因为引用值相同了已经。
在这里插入图片描述

因为对 Target.prototype 进行了操作,Target.prototype.constructor已经变了。因此需要归位,同时设置一个超类,可以查到 Target.prototype 最终继承自谁,可有可无。

	function inherit(Target, Origin){
		function F(){};
		F.prototype = Origin.prototype;
		Target.prototype = new F();
		Target.prototype.constructor = Target;//归位
		Target.prototype.uber = Origin.prototype;//超类
	}

最后一步,用一个立即执行函数,把媒介 function F(){} 有关的变成闭包,私有化,外面访问不了,这就是最终版的圣杯模式。

	var inherit = (function(){
        var F = function(){};
        return function(Target,Origin){
            F.prototype = Origin.prototype;
            Target.prototype = new F();
            Target.prototype.constructor = Target;   
            Target.prototype.uber = Origin.prototype; 
        }
    }())
    inherit(Son,Father)
    var son = new Son();
    var father = new Father();

这时,再对 Target.prototype 添加一些自己的属性和方法也不会影响到 Origin

5. 拷贝继承

就是直接把 Parent 上不变的属性写在原型上,再用拷贝函数将父对象的prototype对象中的属性,一一拷贝给Child对象的prototype对象,这就涉及到了深拷贝浅拷贝的问题了

参考:https://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值