js原型对象-原型链-继承

js原型对象-原型链-继承

原型对象

原型对象:只要创建了一个新函数,就会根据一些特定的规则为该函数创建一个prototype属性,这个属性指向的对象就是该新函数的原型对象。(默认情况下,所有原型对象都会自动获取一个constructor属性,这个属性是一个指向prototype属性所在函数的指针)
原型对象的优点:可以让所有对象实例共享它所包含的属性和方法。
实例如下:
function Test(){
}
Test.prototype.name=“张三”; //实例属性添加到原型对象中
Test.prototype.age=“27”;
var test1= new Test(); //初始化实例
alert(test1.name); //zhangsan
alert(test1.age); //27
var test2= new Test(); //初始化实例
alert(test2.name); //zhangsan
alert(test2.age); //27

实例和原型对象之间的关系图
js原型对象-原型链-继承

(注释:当调用构造函数创建一个新实例后,该实例内部将包含一个指针,指向构造函数的原型对象,ECMA-262第五版中管这个指针叫做[[Prototype]])

原型链-继承

继承方式:许多面向对象语言都支持两种继承方式,接口继承实现继承,接口继承只继承方法签名,而实现继承则继承实际的方法。由于函数没有签名,在ECMAScript中无法实现接口继承。ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的
原型链:举例说明吧,以上边原型对象中举的实例为例,简单回顾一下构造函数、原型、和实例的关系,每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的指针。
假设一下:假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象中包含一个指向另一个原型的指针,相应的另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条关系,就是所谓的原型链

实例如下:
实现原型链有一种基本模式,其代码如下所示
function WebSum(){
this.name=“zhangsan”;
}
WebSum.prototype.getSumValue = function(){
return this.name;
}
function WebOne(){
this.name=“zhang”;
}
WebOne.prototype = new WebSum(); //创建实例的方式继承WebSum
var oneChild = new WebOne();
alert(oneChild .getSumValue); //zhangsan

实例的原型链图如下
js原型对象-原型链-继承

(注释:WebOne继承了WebSum,而继承是通过创建WebSum实例,并将该实例赋给WebOne.prototype实现的,实现的本质是重写原型对象,以上例子中我们没有使用WebOne默认提供的原型,而是给它换了一个新原型,这个新原型就是WebSum的实例。新原型不仅具有作为一个WebSum实例所拥有的全部属性和方法,而且其内部还有一个指针,指向了WebSum的原型。
最终结果是这样: oneChild指向WebOne的原型,WebOne的原型又指向WebSum的原型
最后,例如调用oneChild .getSumValue()会经历三个步骤,1、搜索实例,2、搜索WebOne.prototype,3、搜索WebSum.prototype,最后一步才会找到该方法。在找不到属性或方法的情况下,搜索过程会一环一环的前行到原型链末端才会停下来。)