标签:
ECMAScript是高度抽象的面向对象语言,处理对象的。同样也有基本类型,但是他们在需要的情况下,也可以转型成对象。
定义: 对象是拥有一系列属性以及唯一的原型对象。那原型对象可能是对象,也可能为空。
让我们看一个基本对象的例子。对象的原型是通过内部的[[Prototype]]来引用的。然而,我们将会用 __<internal_property>__
下化线符号替代双中括号,那么对于原型对象: __proto__。
对于下面代码:
var foo = { x: 10, y:20 };
我们的结构具有两个明确的属性和一个内部__proto__属性,__proto__属性是对foo的原型的引用。
那么这些属性有什么用呢?让我们看一看原型链来回答这个问题。
原型对象仅仅是简单对象,以及或许拥有他们各自的属性。如果一个原型引用了非空对象到它的原型属性上,依次类推,这就叫做原型链。
原型链是对象的有限链,用它来实现继承和分享属性。
考虑一下,当我们有两个对象,他们只有很小的部分不同,其他的都相同。很明显,对于一个好的系统设计,我们自然希望能重用相似的功能/代码,
而不用去重复这段功能/代码在每个单一的对象。在基于类的系统里,这段重复代码利用称做类继承。把类似的功能集成到A类,提供类B,C去继承自
类A,让他们各自有附加的不同之处。
ECMAScript语言没有类的概念。然而,代码复用是没有太大的不同(甚至在某些方面,它比类式语言更有扩展性),通过原型链来实现的。
这种继承称为委托继承(更接近于ECMAScript,基于原型继承)。
类似例子里的类A,B,C, 在ECMAScript里你可以创建对象:a,b,和c。这样,a对象存放的是对象b,c相同的部分。对象b,c存放的是他们
各自的属性或方法。
var a = { x: 10, calculate: function( z ){ return this.x + this.y + z; } }; var b = { y: 20, __proto__: a }; var c = { y: 30, __proto__:a } b.calculate( 30 ); // 60 c.calculate( 40 ); //80
很简单,不是吗?我们看到对象b,c可以访问到 calculate 方法,它是定义在a对象里的。这就是通过原型两来实现的。
这个简单规则: 如果一个属性或方法在它自己的对象里没有找到(比如:该对象自身没有这个属性),这样就会在原型链里
试图去访问这个属性或方法。如果在原型对象里没有找的话,那么会在该原型对象的原型对象里去寻找,依次类推,到整个原型链(
类似于类链)。第一次找到就会返回。这样,找到的属性称为继承属性。如果向上找完整个原型链,都没有找到该属性的话,那么就
返回undefined。
注意到 this 的值是在继承的方法里被设置为原始对象,而不是原型对象,在该对象找到这个方法的。比如:例子里的 this.y 是来自
b和c,而不是来自a的。然而,this.x 是通过原型链机制取自a的。
如果原型属性没有明确指定了对象,那么默认的__proto__的值就是Object.prototype. Object的Object.prototype也有一个__proto__,这个是链的终端,
并被设置为空。
下面的图片说明了the继承层次关于我们的对象a,b,c:
标签:
原文地址:http://www.cnblogs.com/branches/p/4883506.html