Javascript 为什么这个对象中有一个额外的原型';s原型链?

Javascript 为什么这个对象中有一个额外的原型';s原型链?,javascript,Javascript,我编写了一个名为protoDepth的函数,用于计算对象原型链的深度: function protoDepth(obj) { var depth = 0

我编写了一个名为
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++
,我认为只会执行两次:

  • 深度
    0
  • b
    的原型是
    a
    ;深度为
    1
  • a
    的原型是
    对象
    ;深度为
    2
  • Object
    的原型是
    null
    ;故事结束了
但这是错误的。似乎
a
的原型是
a
。以下是第一行执行的本地范围:


这是怎么回事?为什么A是A的
\uuuuuuuuuuuuuuu
?既然我没有设置
A.prototype
,那么默认情况下它不是
对象吗?

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

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
现在,结果是3,因为原型链包含:
B.prototype
A.prototype
Object.prototype

Fiddle(我添加了一些
console.log
调用以显示结果),调试器现在显示如下:

B {constructor: function}
  __proto__: B
    constructor: function B() { }
    __proto__: A
      constructor: function A() { }
      __proto__: Object
既然我没有设置
A.prototype
,默认情况下它不是对象吗


不,默认情况下它是一个空对象(与
函数A
一起创建)。所以你的
b
原型链是
a
==b.prototype
),然后是
a.prototype
,然后是
对象。prototype
,然后是
null

,默认情况下,每个构造函数都有自己独特的原型对象。该对象是一个普通对象,因此它将对象原型作为其原型。“默认情况下,每个构造函数都有自己独特的原型对象”否,而不是
函数。prototype
。每个函数实例都有一个“原型”属性,该属性被初始化为一个新的、唯一的对象。如果您创建两个单独的函数(如“A”和“B”),每个函数都将有一个不同的原型对象。执行此测试的一个更简单的方法是:设置:
var A=object.create(object.create(object.create({})))
,测试:
expect(protoDepth(A))。toBe(4)
非常感谢。我在这里的主要误解是,
对象
当然是一个函数。