JavaScript__proto__原型链深入分析
JavaSctipt之prototype原型深入分析: prototype的属性是副本,引用,还是固定的查找方式?>>
,我们已经得出结论:从自身延原型链向上查找的方式:
访问对象object.xxx的属性时,如果object自己没有xxx属性,则向上延原型链查找,如果找到,则输出,没找到,则输出undefined.
PS: 因为每个对象和原型都有一个原型(注:原型也是一个对象 ),对象的原型指向对象的父,而父的原型又指向父的父,我们把这种通过原型层层连接起来的关系撑为原型链。这条链的末端一般总是默认的对象原型。
现在我们思想一下,在原型链上,是靠什么来找到原型链的上一个结点的呢??
查询资料后,得出:
每个对象都有一个__proto__属性,原型链上的对象正是依靠这个__proto__属性连结在一起的!
1)下面,我们先测试一下"__proto__是否指向实例对象的原型prototype对象的引用":
//
输出:
username: zhangsan __proto__的确是指向其原型对象的引用!
//
实例person的__proto__属性的确是引用了Person.prototype对象!,如图:
结论:
[实例].__proto__是指向其原型对象的引用!
2)下面,我们利用__proto__来模拟一下原型链的继承,来再次验证__proto__的作用:
//
输出:
所有对象都继承于Object,原型链的顶端就是Object.prototype
原型链连接前,retangleIns.getArea = undefined
原型链连接前,retangleIns.getArea = undefined
原型链连接后,retangleIns.getArea() = area: 20
原型链连接后,retangleIns.getArea() = edge: 4
//
如图:
原型链连接前:
分析: 原型链连接前,retangleIns对象,Retangle_prototype对象,Shape_prototype对象 并无直接关系,因为这些对象都是Objecgt类型的实例,所以这些对象的__proto__属性引用了Object.prototype对象!
而此时retangleIns.getArea,retangleIns.getEdge当然是undefined!
原型链连接后:
分析:
Retangle_prototype.__proto__ = Shape_prototype;
retangleIns.__proto__ = Retangle_prototype;
以上两句执行后,3个对象就通过__proto__属性连接在一起,形成一条原型链!
而retangleIns.getArea() 和retangleIns.getArea()的执行成功,更充分证明了:
每个对象都有一个__proto__属性,原型链上的对象正是依靠这个__proto__属性连结在一起的!
对于原型链上的一个对象obj,那么访问obj.xxx属性(方法也是属性)的过程是: 如果自身有xxx属性,则访问它,如果没有,就通过__proto__属性找到其原型链的上一级原型对象,看它有没有xxx属性,如此递归查找,直至找到xxx属性或到了原型链顶端Object.prototype对象为止!
在此,引用一下<<酷壳网陈皓:再谈JavaScript面向对象编程>>对__proto__的解释:
__proto__成员严格的说这个成员不应该叫这个名字,__proto__是Firefox中的称呼,__proto__只有在Firefox浏览器中才能被访问到。做为一个对象,当你访问其中的一个成员或方法的时候,如果这个对象中没有这个方法或成员,那么Javascript引擎将会访问这个对象的__proto__成员所指向的另外的一个对象,并在那个对象中查找指定的方法或成员,如果不能找到,那就会继续通过那个对象的__proto__成员指向的对象进行递归查找,直到这个链表结束。
PS: 在Chrome也可以使用__proto__属性的!
参考: