第一步是了解什么constructor
and prototype
都是关于。这并不难,但必须放弃古典意义上的“继承”。
构造函数
The constructor
财产does not在您的程序中造成任何特定的影响,除了您可以查看它以了解哪个函数与运算符结合使用new
创建你的对象。如果您输入new Bar()
这将是Bar
你输入了new Foo
这将是Foo
.
原型
The prototype
属性用于查找,以防相关对象不具有所需的属性。如果你写x.attr
, JavaScript 会尝试寻找attr
among x
的属性。如果找不到,它会查找x.__proto__
。如果它也不存在,它将查找x.__proto__.__proto__
等等只要__proto__
被定义为。
那么什么是__proto__
这有什么关系prototype
?简而言之,prototype
用于“类型”,而__proto__
用于“实例”。 (我用引号这么说是因为类型和实例之间实际上没有任何区别)。当你写的时候x = new MyType()
,发生的事情(除其他外)是x.__proto___
被设定为MyType.prototype
.
问题
现在,以上内容应该是您导出自己的示例含义所需的全部内容,但要尝试回答您的实际问题; “为什么要写这样的东西”:
Bar.prototype.constructor = Bar;
我个人从未见过它,我觉得它有点愚蠢,但在你给出的上下文中,它意味着Bar.prototype
-object(通过使用创建new Foo(42)
)将构成为已创建Bar
而不是Foo
。我想这个想法是一些类似于 C++/Java/C# 的语言,其中类型查找(constructor
property)将始终产生最具体的类型,而不是原型链中更通用的对象的类型。
我的建议:不要过多考虑 JavaScript 中的“继承”。接口和 mixins 的概念更有意义。并且不检查对象的类型。检查所需的属性(“如果它像鸭子一样行走并且像鸭子一样嘎嘎叫,那么它就是鸭子”)。
当 JavaScript 所拥有的只是如上所述的原型机制时,试图强制 JavaScript 进入经典的继承模型,这就是导致混乱的原因。很多人建议手动设置constructor
-property 可能试图做到这一点。抽象很好,但是这种手动分配构造函数属性并不是 JavaScript 的惯用用法。