问题描述
我看到很多这样的代码:
I see a lot of code like this:
function Base() {}
function Sub() {}
Sub.prototype = new Base();
但是,如果您这样做:
s = new Sub();
print(s.constructor == Sub);
这是错误的.这对我来说似乎令人困惑,因为 s 的构造函数确实是 Sub.这样做是否传统/更好?
This is false. This seems confusing to me, since s's constructor is, indeed, Sub. Is it conventional/better to do this?
function Base() {}
function Sub() {}
Sub.prototype = new Base();
Sub.prototype.constructor = Sub;
还是真的不重要?
推荐答案
'constructor' 不像它看起来那样做.除了它的非标准性之外,这也是避免使用它的一个很好的理由 - 坚持使用 instanceof 和原型.
'constructor' doesn't do what it looks like it does. This, in addition to its non-standardness, is a good reason to avoid using it - stick with instanceof and prototype.
从技术上讲:'constructor' 不是 's' 实例的属性,它是显示出来的 'Sub' 原型对象的属性.当您在 Mozilla 中创建Sub"函数时,您会得到一个新生成的默认 Sub.prototype 对象,出于礼貌,该对象具有一个指向 Sub 函数的构造函数".
Technically: 'constructor' is not a property of the 's' instance, it is a property of the 'Sub' prototype object showing through. When you create the 'Sub' function in Mozilla, you get a newly-minted default Sub.prototype object which has a 'constructor' pointing back to the Sub function as a courtesy.
然而,您随后用新的 Base() 替换了该原型.带有返回 Sub 的链接的原始默认原型丢失;相反, Sub.prototype 是 Base 的一个实例,没有任何覆盖的构造函数"属性.所以:
However you then replace that prototype with a new Base(). The original default prototype with the link back to Sub is lost; instead, Sub.prototype is an instance of Base without any overriding 'constructor' property. So:
new Sub().constructor===
Sub.prototype.constructor===
new Base().constructor===
Base.prototype.constructor===
Base
...一直到最基本的对象,其原型您没有改变.
...all the way down to the most basic object whose prototype you didn't change.
这样做是否传统/更好?
在处理 JavaScript 对象/类时,没有一种约定;每个图书馆的元类系统的行为略有不同.我还没有看到手动将构造函数"写入每个派生类的方法,但如果您真的想要真正的构造函数可用,这似乎是一个很好的解决方案;它还将使代码与不为您提供构造函数"的浏览器/引擎兼容.
When dealing with JavaScript objects/classes there is no one convention; every library's metaclass system behaves slightly differently. I haven't seen one that writes 'constructor' to each derived class manually, but it seems as good a solution as any if you really want to have the real constructor available; it will also make the code compatible with browsers/engines that don't give you 'constructor'.
不过,我会考虑给它一个不同的名字,以避免与现有的和行为不同的构造函数"属性混淆.
I'd consider giving it a different name, though, to avoid confusion with the existing and differently-behaving 'constructor' property.
这篇关于JavaScript 中原型继承的约定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!