简而言之:
new something2() instanceof something2 === false
与此相关的,如果你扩展你的榜样使用原型属性
Something.prototype.method = function() { };
something2.prototype.method = function() { };
你会发现,原型是不是在后一种情况下继承:
typeof (new Something()).method === "function"
type (new something2()).method === "undefined"
该rea l答案是你正在攻击完全不同的基础机器。调用new
调用[[Construct]]机制,该机制涉及根据构造函数的.prototype
属性设置[[Prototype]]属性。
但是一个有趣的事情发生在[[Construct]]算法的步骤8--10:设置一个新的空对象,然后附加其[[Prototype]]后,它会执行[[Call] ]到实际的构造函数,使用这个新的空加原型对象作为this
。然后,在第9步中,如果事实证明该构造函数返回了一些东西 - 它抛弃了原型绑定,传递为this
的对象,它一直花费在设置上!
注意:您可以访问对象的[[原型](这是由不同构造的.prototype
)与Object.getPrototypeOf
:
Object.getPrototypeOf(new Something()) === Something.prototype // steps 5 & 6
Object.getPrototypeOf(new something2()) === Object.prototype // default
回答一些元问题:
- 不,请不要大写
something2
,因为它是工厂函数而不是构造函数。如果某些东西是大写的,则预计会有构造函数语义,例如new A() instanceof A
。
- 如果您担心全局命名空间遭到破坏,您应该开始使用strict mode,将
"use strict";
放在文件的顶部。严格模式的很多很好的清理之一是this
默认为undefined
,而不是全局对象,例如,在构造函数尝试将属性附加到undefined
时调用构造函数而不使用new
将导致错误。
- 工厂函数(又称“闭包模式”)通常是构造函数和类的合理替代,只要您(a)不使用继承; (b)不构造太多的对象实例。后者是因为在闭包模式中,每个方法的新实例附加到每个新创建的对象,这对内存使用来说并不好。国际海事组织(IMO)最大的回报就是使用"private" variables(这是一个good thing,并且别让别人告诉你:P)。
有点警惕先生克罗克福德。虽然他有很多好话要说,但他确实有不同意见。 – staticsan 2012-04-26 06:50:37