为什么在这个对象的原型链中有一个额外的原型?

时间:2014-01-19 16:55:18

标签: javascript

我写了一个名为protoDepth的函数来计算对象原型链的深度:

function protoDepth(obj) {                                                                                                                                                                   
  var depth = 0                                                                                                                                                                              
    , proto                                                                                                                                                                                  
  while (proto = Object.getPrototypeOf(obj)) {                                                                                                                                               
    obj = proto                                                                                                                                                                              
    depth++                                                                                                                                                                                  
  }                                                                                                                                                                                          
  return depth                                                                                                                                                                               
}

然后我为这个函数写了一个测试,它出乎意料地失败了:

describe('`protoDepth`:', function() {                                                                                                                                                
  function A() {}                                                                                                                                                    
  function B() {}                                                                                                                                                    
  var a, b                                                                                                                                                                                 

  beforeEach(function() {                                                                                                                                                                  
    a = new A                                                                                                                                                                              
    B.prototype = a                                                                                                                                                                        
    b = new B                                                                                                                                                                              
  })                                                                                                                                                                                       

  it('provides the correct prototype depth.', function() {                                                                                                                                 
    expect(protoDepth(b)).toBe(2)                                                                                                                                                     
  })                                                                                                                                                                                       
})  

我预计深度为2;也就是说,我认为depth++只会被执行两次:

  • depth0
  • b的原型是a;深度为1
  • a的原型是Object;深度为2
  • Object的原型是null;故事的结尾。

但这是错误的。 a的原型似乎是a。这是第一行执行的本地范围:

enter image description here

enter image description here

这里发生了什么?为什么A是__proto__?由于我没有设置A.prototype,默认情况下不是Object吗?

2 个答案:

答案 0 :(得分:1)

这就是B的原型应该如何设置:

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

现在,结果是3,因为原型链包含:B.prototypeA.prototypeObject.prototype

小提琴here(我添加了一些console.log调用来显示结果),调试器现在显示:

B {constructor: function}
  __proto__: B
    constructor: function B() { }
    __proto__: A
      constructor: function A() { }
      __proto__: Object

答案 1 :(得分:1)

  

由于我没有设置A.prototype,默认情况下不是对象吗?

不,默认情况下它是一个空对象(与function A一起创建)。因此,b的原型链是a== B.prototype),然后是A.prototype,然后是Object.prototype,然后是null