码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript核心-继承-原型链

时间:2015-05-06 23:07:43      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:

继承是面向对象的编程的一大特性,很多OO语言都支持两种继承方式:接口继承和实现继承。在ECMAScript中,由于函数没有签名,所以无法实现接口继承,只有实现继承。

实现继承主要是依靠原型链来实现的。


简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而对象的每个实例都有一个指向原型对象的内部指针。


再回顾一下原型对象的用途:用途是包含可以由特定类型的所有实例共享的属性和方法。


原型对象也是一个简单的对象,如果我们让一个原型对象等于另一个类型的实例,也就是说可以让一个原型对象的原型是一个非null的引用,那么此时的原型对象将包含一个指向另一个原型的指针。加入另一个原型又是另一类型的实例,那上述关系依然成立,如此层层递进,就构成了原型链。


总的来说,原型链就是用来实现继承和共享属性的有限对象链。


当我们读取一个实例的属性时,首先会在实例中搜索该属性。如果没有找到该属性,就会在实例的原型中继续搜索该属性。当我们利用了原型链来实现继承时,如果在实例的原型中还没找到该属性,就会在原型的原型中继续寻找,并以此类推,遍历整个原型链。如果遍历了整个原型链还是没找到这个属性的话,就返回undefined值。


因为所有的引用类型都默认继承自Object,所有默认原型都包含一个内部指针,指向Object.Prototype。这也是所有自定义类型都会继承toString(),valueOf()等默认方法的根本原因。


使用原型链来继承会存在以下两个问题:

1.包含引用类型值的原型属性会被所有的实例所共享。这也是我们一般在构造函数中,而不是原型中定义属性的原因。在通过原型来实现继承时,原型实际上会变成另一个类型的一个实例,于是这个实例的属性也就变成了现在原型的属性了。

2.在构造子类型的实例时,不能像超类型的构造函数中传递参数。


解决以上问题的一个方法就是采用组合继承,就是将原型链和借用构造函数的技术组合到一起的一种继承模式。

思路就是使用原型链实现对原型属性和方法(主要是方法)的继承,而通过借用构造函数来实现对实例属性的继承。下面是例子:

function SuperType(name){
	this.name = name;
	this.colors = ["red","yellow"];
}

SuperType.prototype.sayName = function(){
	alert(this.name);
};

function SubType(name,age){
	//借用父类的构造函数,这样SubType的实例中就有了name和colors这两个实例属性,这两个属性就是每个实例独有的了
	<span style="color:#FF0000;">SuperType.call(this,name);</span>
	this.age = age;
}

//继承方法
SubType.prototype = new SuperType();
//这是把SubType的constructor属性改回来,创建SubType实例时调用SubType的构造函数
<span style="color:#FF0000;">SubType.prototype.constructor = SubType;</span>

//在SubType的新原型上添加一个方法
SubType.prototype.sayAge = function(){
	alert(this.age);
};

var instance1 = new SubType("zhu",24);
instance1.colors.push("black");
alert(instance1.colors);  //red,yellow black
instance1.sayName();  //zhu
instance1.sayAge(); 	//24

var instance2 = new SubType("li",23);
instance2.colors.push("blue");
alert(instance2.colors);  //red,yellow blue
instance2.sayName();  //li
instance2.sayAge(); 	//23
上面的代码实例化了两个SubType的实例instance1和instance2,它们既拥有了自己的是、属性,包括colors,同时也有了相同的方法sayName()。

这种组合继承避免了原型链和借用构造函数的确定,融合了其优点,也是JavaScript中最常用的一种继承模式。可以作为模板掌握。


JavaScript核心-继承-原型链

标签:

原文地址:http://blog.csdn.net/zhuyunhe/article/details/45539635

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!