_proto_理解

一个对象就是一个属性集合,并拥有一个独立的prototype(原型)对象。这个prototype可以是一个对象或 者null。

一个对象的prototype是以内部的[[Prototype]]属性来引用的。但是,在示意图里边 我们将会使用__<internal-property>__下划线标记来替代两个括号,对于prototype对象来说是:__proto__。

对于以下代码:

var foo = {

  x: 10,

  y: 20

};


我们拥有一个这样的结构,两个明显的自身属性和一个隐含的__proto__属性,这个属性是对foo原型对象的引用:

 

这些prototype有什么用?让我们以原型链(prototype chain)的概念来回答这个问题。

原型对象也是简单的对象并且可以拥有它们自己的原型。如果一个原型对象的原型是一个非null的引用,那么以此类 推,这就叫作原型链。

原型链是一个用来实现继承和共享属性的有限对象链。

考虑这么一个情况,我们拥有两个对象,它们之间只有一小部分不同,其他部分都相同。显然,对于一个设计良好的 系统,我们将会重用相似的功能/代码,而不是在每个单独的对象中重复它。在基于类的系统中,这个代码重用风格叫 作类继承-你把相似的功能放入类A中,然后类 B和类 C继承类 A,并且拥有它们自己的一些小的额外变动。

ECMAScript中没有类的概念。但是,代码重用的风格并没有太多不同(尽管从某些方面来说比基于类(class-based) 的方式要更加灵活)并且通过原型链来实现。这种继承方式叫作委托继承(delegation based inheritance)(或者,更贴 近ECMAScript一些,叫作原型继承(prototype based inheritance))。

 

跟例子中的类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 };
// call the inherited method b.calculate(30); // 60 c.calculate(40); // 80

我们看到b和c访问到了在对象a中定义的calculate方法。这是通过原型链实现的。


规则很简单:如果一个属性或者一个方法在对象自身中无法找到(也就是对象自身没有一个那样的属性),然后它会 尝试在原型链中寻找这个属性/方法,

如果这个属性在原型中没有查找到,那么将会查找这个原型的原型,以此类推, 遍历整个原型链(当然这在类继承中也是一样的,当解析一个继承的方法的时候-我们遍历class链( class chain))。第一个被查找到的同名属性/方法会被使用。因此,一个被查找到的属性叫作继承属性。如果在遍历了整个 原型链之后还是没有查找到这个属性的话,返回undefined值。
注意,继承方法中所使用的this的值被设置为原始对象,而并不是在其中查找到这个方法的(原型)对象。也就是, 在上面的例子中this.y取的是b和c中的值,而不是a中的值。但是,this.x是取的是a中的值,并且又一次通过原型 链机制完成。

 

如果没有明确为一个对象指定原型,那么它将会使用__proto__的默认值 -Object.prototype。Object.prototype对象自身也有一个__proto__属性,这是原型链的终点并且值为null。
下一张图展示了对象a,b,c之间的继承层级:

 

注意: ES5标准化了一个实现原型继承的可选方法,即使用Object.create函数:

var b = Object.create(a, {y: {value: 20}});

var c = Object.create(a, {y: {value: 30}});

转载于:https://www.cnblogs.com/js0618/p/6564086.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值