这可能是最安全的方式(案例 A):
var myClass = function() { };
myClass.prototype = {
doSomething : function() { alert('Something'); }
};
这是替代方案(案例 B):
var myClass = function() {
this.doSomething = function() { alert('Something'); };
};
我的印象是,通过如案例 B 所示执行此操作,doSomething 将成为成员,并且该函数将为我实例化的每个 myClass 对象定义一次,以便它在内存中存在 100 次,代表 100 个实例,而在情况 A 中,该函数将仅存在于内存中的一个位置,不同的实例将仅引用原型(prototype)。
我理解正确吗?
作为奖励问题:当按照案例 B 进行操作时,chrome 开发人员为我提供了 doSomething 的智能感知,但我必须展开 __proto__ 才能看到它。为什么它没有出现在对象本身上?也就是说,为什么原型(prototype)成员不显示在对象上,而是卡在 __proto__ 上?如果 __proto__ 堆栈会变平并直接显示在对象上,我会更喜欢。是否有另一个 Case 会允许这种情况发生?
最佳答案
首先,在情况 B 中,您只是创建一个全局函数,而不是将其附加到实例。你的意思是:
this.doSomething = function() { }
其次,第一个会更快。虽然我现在找不到链接,但 jQuery 主管 John Resig 对此发表了一篇详细的博客文章,展示了方法的原型(prototype)继承与实例上声明的方法的速度测试。继承明显更快。
就精神而言,我一直非常喜欢继承。这是可重用的跨实例功能的地方。将它添加到每个实例的唯一好处是允许您在构造函数中的单个方便的闭包内声明方法,仅此而已。
如果这是您喜欢模式 B 的原因,则可以这样做,同时仍然 a) 继承方法; b) 不在每次实例化时都重新声明它们。
function SomeClass() {
if (!SomeClass.prototype.someMethod) {
SomeClass.prototype.someMethod = function() {}
}
}
不过,这会稍微减慢初始实例化的速度,因为它负责设置原型(prototype) - 而不是实例化过程的真正工作。
您的两个案例之间还存在编程差异:
function SomeClass(name) {}
SomeClass.prototype.someMethod = function() {};
var instance = new SomeClass();
console.log(!!instance.someMethod); //true
console.log(instance.hasOwnProperty('someMethod')); //false
最后一行是假的,因为方法是继承的,不属于实例。对于您的模式 B,这将解析为 true。
关于javascript - 在构造函数中定义函数会比将其附加到原型(prototype)消耗更多的内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11948333/