继承及原型链解析
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 上创建不必要、多余的属性,与此同时,原型链还能保持不变,这种继承方式是实现基于类型继承的最有效方式。
实现原型链的基本模式:
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 上创建不必要、多余的属性,与此同时,原型链还能保持不变,这种继承方式是实现基于类型继承的最有效方式。
相关文章推荐
- 创建对象及原型模式
- 函数类型的理解
- 数组类型的方法
- JS倒计时
- js正则匹配出所有图片及所有图片地址src
- transformjs污染了DOM?是你不了解它的强大
- JS倒计时
- JS冒泡排序
- javascript数据类型检测typeof
- 关于Json
- 关于jsonp跨域
- JS 来回切换图片
- Javascript 图片闪烁
- 转→js数组遍历 千万不要使用for...in...
- Javascript复选框
- 【javascript之Dom编程艺术】五
- 一款js时间操作插件 Moment.js
- Javascript执行流总结
- IE6,7,8"开发人员工具"使用详解下(浏览器模式、文本模式、JavaScript调试、探查器)
- JavaScript模式