第一步是理解constructor和prototype都是关于。这并不难,但我们必须放弃古典意义上的“继承”。
构造函数
这个constructor财产不导致程序中的任何特殊效果,除非您可以查看它以查看与运算符一起使用的函数。new来创建你的对象。如果你打字new Bar()它将是Bar你打字new Foo它将是Foo.
原型
这个prototype属性用于在所述对象没有所请求的属性的情况下进行查找。如果你写x.attr,JavaScript将试图找到attr在x的属性。如果它找不到它,它将查找x.__proto__..如果它也不在那里,它就会往里面看x.__proto__.__proto__等等只要__proto__被定义。
所以什么是__proto__它和这件事有什么关系prototype?不久,prototype代表“类型”__proto__代表“实例”。(我这样说是用引号表示的,因为类型和实例实际上没有任何区别)。当你写x = new MyType(),发生的事情(除其他外)是x.__proto___设置为MyType.prototype.
问题
现在,您只需通过上面的内容来推导出您自己的示例的含义,而是尝试回答您的实际问题;“为什么要写类似的东西”:
Bar.prototype.constructor = Bar;
我个人从未见过它,我觉得它有点傻,但在你给出的上下文中,这意味着Bar.prototype-对象(通过使用new Foo(42))将摆出已经被创造出来的姿势。Bar而不是Foo..我想这个想法是一些类似于C+/Java/C#的语言,其中类型查找(constructor属性)总是会产生最特定的类型,而不是原型链中更高的泛型对象的类型。
我的建议是:不要过多地考虑JavaScript中的“继承”。接口和混合的概念更有意义。也不要检查对象的类型。检查所需的属性(“如果它像鸭子一样走路,像鸭子一样嘎嘎叫,那就是鸭子”)。
试图将JavaScript强制进入一个经典的继承模型,而它所拥有的只是上面描述的原型机制,这就是造成混乱的原因。建议手动设置constructor-财产可能就是这样做的。抽象是可以的,但是构造函数属性的手动分配并不是JavaScript的惯用用法。