您的位置:首页 > Web前端 > JavaScript

js 组合继承(使用原型模式和构造函数模式)和原型式继承

2016-09-13 08:37 681 查看
构造函数和原型模式各有很大用武之地,构造函数用于定义实例私有属性,而原型模式用于定义共享方法和属性,所以此模式下创建的实例都会有一份自己构造模式所定义的实例属性的副本,但又同时共享着原型模式所定义的原型链上的属性与方法,最大限度节约内存。可以参考我另一篇组合继承文章,下面给出一个原型模式和构造函数模式的组合:

function Person(name){
this.name=name;
this.friends=["Shelby","Court"];
}

Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}
function Man(name, job){
Person.call(this, name);
this.job = job;
}

//实现继承
Man.prototype = new Person();
Man.prototype.constructor = Man;
Man.prototype.sayJob = function(){
alert(this.job);
}

var man1 = new Man("allen", "student");
var man2 = new Man("mary", "nurse");
var man1.friends.push("Van");

alert(man1.friends);                    //"Shelby,Count,Van"
alert(man2.friends);   			//"Shelby,Count"
alert(man1.friends === man2.friends);   //false
alert(man1.sayName === man2.sayName);   //true
alert(man1.sayJob === man2.sayJob);     //true




per
bdf1
son1和person2是两个不同的实例,所以他们的两个数组属性也是不同的,一个改变并不会影响另一个,而两个friends的地址显然也是不同的。

但两个实例原型链上的属性和方法是同一个,所以共享的属性方法的引用是相同的,但其实我们可以看到在实例man1的原型上即Person,它上面有两个无用的共享属性。

总体来说,new实现原型继承父亲的prototype  =》 将父元素的实例preson1赋值给子元素的prototype  =》  new实现原型继承子元素的prototype。

归纳一下,最终结果从上到下用__proto__继承,父亲(Person) =》 父亲实例  =》 子实例。

另外提一下原型式继承,比较特别的是它是用一个现有的对象去继承该对象的类,说白了就是把前面的new Man()替换为man1

function object(o){
var F = function(){}
F.prototype = o
return new F()
}

封装起来的原理大概就是这样,es5规范中定义的Object.create()实现了同样的效果

var person = new Person();
var man1 = object(person);


有兴趣可以自己实现打印一下。上面我们提到组合继承原型链上有一份重复的属性,现在我们可以结合原型链继承的方法对其进行优化。

其实只需要一步,将new Person()换成object(Person.prototype),不经过构造函数直接继承,这种方法叫做寄生组合式继承。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐