Js中的原型链的解释

A)      关于prototype chain有几点说明:

  a.      这个链的终点是Objectprototype对象:Object.prototype

  b.      所有的对象在默认的情况下都有一个原型(__proto__.

  c.      原型本身也是对象,所以每个原型自身又有一个原型(__proto__),除了Object.ptototype.

关于c这个观点可以用一下面的小程序来证明:

[javascript]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. function A(){}  
  2. console.log(A.prototype.__proto__);//Object {}  
  3. console.log(Object.prototype.__proto__);//null  

 就这上面两个输出,下面做详细的分析,并说明这个proto链是怎么形成的。

1)  先定义一个简单的函数并创建该函数的对象 var a = new A(); 注意,这里a,没有自己的属性,它的所有的属性都从原型对象上继承而来)现在看看内存中这个对象的具体情况

 

                                                                                          图 1.1 

观察图1.1,可以发现a对象的__proto__属性,这个论证了观点b的正确性。观察prototype对象有一个__proto__属性(绿色方框所示)。这个就说明了观点b的正确性。

但是,prototype的__proto__所代表的对象是谁呢?查看@37891发现,这个对象是一个Object对象,其实说白了就是Object.prototype所指向的对象。下面给出该对象的内存情况:

                                                图 1.2

观察这个对象的constructor,其指向Object的构造器。对比图1.1可以发现,这个对象是没有__proto__属性的,这个对象正是a对象所在的proto链条的终点:Object.pototype.

结合上面的说明,可以得到如下图示:


                                       图 1.3


注意:沿着红色箭头组成了proto链!!!所以console.log(A.prototype__proto__)为Object{},而Object.prototype.__proto__为null.

B)      通过这个prototype chain可以实现属性的继承,例程如下:

[javascript]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. function A(x){  
  2.     this.x = x ;  
  3.   }  
  4.   
  5.   function B(y) {  
  6.     this.y = y;  
  7.   }  
  8.   
  9.   B.prototype = new A(1);  
  10.   
  11.   function C(z) {  
  12.     this.z = z;  
  13.   }  
  14.   
  15.   C.prototype = new B(2);  
  16.   
  17.   var c = new C(3);  
  18.   var sum = c.x+c.y + c.z;//sum == 6  
可以通过chrome浏览器的Take Heap Snapshot来查看对象c的prototype chain。如下图
 

                    图 1.4

 先逐步分一下各个对象的内存分析图:查看一下@14285对象(A的对象)的prototype chain:(留意一下@后面的数字)。

 
                       图 1.5


用图形表现其prototype chain如下:

                                                图1.6

通过上图分析,有如下关系:


[javascript]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. a.__proto__ === A.prototype,  
  2.   
  3. A.prototype.__proto__===Object.prototype  

再看看@14295所代表的对象(B的对象)的prototype chain:

                                        图1.7


用图形表现其prototype chain如下:

                                  图1.8

[javascript]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. b.__proto__ === B.prototype  
  2.   
  3.   B.prototype.__proto__ === A.prototype  
  4.   
  5.  A.prototype.__proto__ === Object.prototype   

说明:图1.8的B.prototype所代表的对象,其实是图1.6中的对象a,因为B.prototype的@后面的数字和a对象@后面的数字是一样的。所以在这里特地把它们的颜色标识为绿色,以示为同一个对象。其余颜色相同的@+数字,代表着同样的意思。

所以图1.8和图1.7合并起来可以另外表示为:


                                                                  图 1.9

到这里,B的prototype chain已经和A的prototype chain连接起来了。链接起来的关键代码就是B.prototype = new A(1);

同理,再看看对象c的prototype chain:

                     图 2.0

用图形表示为:

                   

                        图  2.2

  C.__proto__=== C.prototype

 C.prototype. __proto__ == a

  注意蓝色@14295,可以得出c. __proto__== b,在代码中体现为C.prototype = new B(2);

所以图2.1还可以表示为:


  同时也可以发现,javascript对象属性搜索的过程是由近到远的顺序,如果c对象中有了y属性,那么C.prototype的属性y是不会访问到的。

Var c = new (3);

c.y = 4;//

var sum = c.x +c.y ;//==5而不是==3

注意代码c.y = 4;这是个赋值操作,而不是取值操作;对于赋值操作,javascript总是在原始对象(在这里是c对象)创建属性或者对已有的属性赋值,而不会去修改原型链。在javascript中只有查询属性(取值操作)时才会体现到继承的存在,而设置属性则和继承无关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值