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

继承及原型链解析

2016-12-28 22:38 260 查看
ECMAScript 只支持实现继承,而且其实现继承主要是依靠原型链来实现的。

实现原型链的基本模式:

function Sup(){
  this.property=true;
}
Sup.prototype.getSupValue=function(){
  return this.property;
};

function Sub(){
  this.subproperty=false;
}
//继承了Sup
sub.prototype=new sup();
sub.prototype.getsubValue=function(){
  return this.subproperty;
};

var instance=new Sub();
alert(instance.getSupValue()); //true

一句话来理解的话,就是把 sup( ) 的实例对象给到了sub( ) 的原型对象,完成继承。
在代码中,并没有使用 sub( ) 默认提供的原型对象,而是给它换了一个原型,即是 sup( ) 的实例,于是新原型不仅具有作为一个 sup( ) 的实例所拥有的全部属性和方法,而且其内部还有一个指针属性 __proto__([[prototype]])指向 sup( )的原型对象。
在这里,调用 instance.getSupValue 会经历三个搜索步骤:
1.搜索实例
2.搜索 sub 的原型对象
3.搜索 sup 的对象对象
值得一提的是,所有函数的默认原型都是 object 的实例,因此默认原型都会包含一个指针,指向 object.prototype , 它才是原型链的顶层。

组合继承(将原型链和借用构造函数的技术组合一起)

function SuperType(name){
     this.name=name;
     this.colors=['red','blue','green']
}
SuperType.prototype.sayName=function(){
     alert(this.name);
};

function SubType(name,gae){
     //继承属性
     SuperType.call(this,nane);
     this.age=age;
}
//继承方法
SubType.prototype=new SuperType();
SubType.prototype.constructor=SubType;
SubType.prototype.sayAge=function(){
     alert(this.age);
};

var instancel=new SubType('joey','18');
instancel.colors.push('black');
alert(instancel.colors); //red','blue','green','black'
instancel.sayName();     //'joey'
instancel.sayAge();      // 18

var instancel=new SubType('xiaoming','8');
alert(instancel.colors); //red','blue','green'
instancel.sayName();     //'xiaoming'
instancel.sayAge();      // 8

组合继承的思路是,使用原型链实现对原型属性和方法的继承,而通过构造函数实现对实例属性的继承。
在这里,SuperType 构造函数定义了两个属性,name 和 colors ,在原型了定义了一个 sayName 方法;然后创建SupType 函数,使用 call 方法继承了 SuperType 的属性,并定义了自己的 age 属性。然后,使用原型链继承 SuperType 的实例,然后又在该新的原型上定义了方法 syaAge,这样一来就可以让两个不同的 SubType 实例分别拥有自己的属性,又可以使用相同的方法。

原型式继承

function objcet(o){
     function F(){}
     F.prototype=o;
     return new F();
}

这是道格拉斯·克罗克福德提出来的实现继承的方法,在 object 函数内部构建一个临时性的构造函数,然后将传入的对象作为构造函数的原型,然后返回这个临时类型的一个新实例,下面看例子:

var person={
     name:'joey',
     friends:['a','b']
4000

}

var one=Object.create(person,{
     name:{
         value:'Greg' 
     }
});
one.friends.push('c');

var two=Object.create(person);
two.name='linda';
two.frieds.push('d');

alert(person.frieds);   //'a','b','c','d'
alert(one.name);        //'Greg'

这种原型式继承,要求必须 有一个对象可以作为另一个对象的基础。
在这个例子中,可以作为另一个对象的基础是 person 对象,我们将它传入到 object.create 方法中,然后会返回一个新的对象,这个新对象会将 person  作为原型,所以它的原型里包含一个基本类型值属性和一个引用类型值相属性,这意味着,person.friedns 不仅属于 person 所有,而且会被 one 和 two共享。
这里的 Object.create 方法接收两个参数,一个是用作新对象原型的对象,(可选的)一个为新对象定义额外属性的对象,格式与 Object.defineProperties( ) 方法相同,以这种方式指定的任何属性都会覆盖原型对象上的同名属性。

寄生式继承

function A(original){
     var clone=object(roiginal); //通过调用函数创建一个新对象
     clone.sayHi=function(){     //以某种方式来增强这个对象
          alert('hi');
     };
     return clone;       //返回这个对象
}
var person={
     name:'joey';
     friedns:['ross','linda']
}
var B=A(person);
B.sayHi();  //hi

寄生式继承是与原型式继承紧密相关的一种思路,与寄生构造函数,工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式增强对象,最后在返回,使用这种继承会由于不能做到函数复用而降低效率,与构造函数模式类似。
在这个例子,基于 A 返回了一个新对象 B,新对象不仅具有 A 所有属性和方法,还有自己定义的 sayHi( ) 方法。

寄生组合式函数

基本模式如下:
function inherit(subType,superType){
     var prototype=Object(superType.prototype); //创建对象 
     prototype.constructor=subType;     //增强对象
     subType.prototype=prototype;       //指定对象
}

例子如下:
function SuperType(name){
     this.name=name;
     this.colors=['red','blue']
}
SuperType.prototype.sayName=function(){
     alert(this.name)'
};
function SubType(name,age){
     SuperType.call(this.name);  //获取SuperType构造函数的属性
     this.age=age;
}
inherit(SubType,SuperType);
SubType.prototype.sayAge=function(){
     alert(this.age);
}

这个实例中的 inherit( ) 函数实现了寄生组合式继承的最简单的形式。这个函数接收两个参数,一个子类型构造函数,一个超类型构造函数;在函数内部第一步先创建超类型原型的一个副本;第二步为创建的俄副本添加 constructor 属性,指向子类型构造函数,从而弥补因重写原型而失去的 constructor 属性;最后一步,将新创建的对象(副本)赋值给子类型的原型。

inherit(SubType,SuperType) 在这个例子中有三个步骤:
1.将超类型的原型对象获取,也就是 SuperType.prototype,创建新的副本。
2.修改这个副本的 constructor 属性,让它指向 SubType。
3.把这个副本赋值给子类型构造函数的原型,也就是  SubType.prototype

这个例子的高效体现在只调用了一次 SuperType 构造函数,并且避免 SubType.protoype 上创建不必要、多余的属性,与此同时,原型链还能保持不变,这种继承方式是实现基于类型继承的最有效方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息