javascript 原型链

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

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

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

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

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

  function A(){}
  console.log(A.prototype.__proto__);//Object {}
  console.log(Object.prototype.__proto__);//null

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

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

 javascript 原型链

                                                                                          图 1.1 

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

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

javascript 原型链

                                                图 1.2

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

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

javascript 原型链

                                       图 1.3


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

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

function A(x){
    this.x = x ;
  }

  function B(y) {
    this.y = y;
  }

  B.prototype = new A(1);

  function C(z) {
    this.z = z;
  }

  C.prototype = new B(2);

  var c = new C(3);
  var sum = c.x+c.y + c.z;//sum == 6
可以通过chrome浏览器的Take Heap Snapshot来查看对象c的prototype chain。如下图
 javascript 原型链

                    图 1.4

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

javascript 原型链 
                       图 1.5


用图形表现其prototype chain如下:

javascript 原型链

                                                图1.6

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


a.__proto__ === A.prototype,

A.prototype.__proto__===Object.prototype

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

javascript 原型链

                                        图1.7


用图形表现其prototype chain如下:

javascript 原型链

                                  图1.8

b.__proto__ === B.prototype

  B.prototype.__proto__ === A.prototype

 A.prototype.__proto__ === Object.prototype 

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

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

javascript 原型链
                                                                 图 1.9

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

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

javascript 原型链

                     图 2.0

用图形表示为:

javascript 原型链                   

                        图  2.2

  C.__proto__=== C.prototype

 C.prototype. __proto__ == a

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

所以图2.1还可以表示为:

javascript 原型链

至此,c的prototype chain 完全构成。最后就可以很清晰的得出程序最终的结果6是如何得到的了

javascript 原型链

当c访问x即c.x时,c对象里有x属性,直接获取它的值1,但是c.y这个属性在c对象里没有,所以会沿着prototype chain查询,在b对象中也就是C.prototype中找到y,取值为2,同理c.z在a对象中找到了z属性。因此sum == 6

  同时也可以发现,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中只有查询属性(取值操作)时才会体现到继承的存在,而设置属性则和继承无关。


javascript 原型链,布布扣,bubuko.com

javascript 原型链

上一篇:SiR-PEG3-TCO硅基罗丹明peg功能化染料反式环辛烯SiR-TCO


下一篇:什么是测试数据【杭州多测师】【杭州多测师_王sir】