在JavaScript中,将函数分配给原型是否有内存性能优势?

3

我看到过这样的说法:将函数添加到对象中会比将函数添加到对象原型中占用更多的内存。

function Obj() {
    this.M = function() { // do something };
}

var o = new Obj();

每次创建Obj实例时,都会创建并应用一个新函数,这会增加内存使用量。如果有1000个Obj实例,就需要创建1000个函数。
function Obj() {

}
Obj.prototype.M = function() { // do something };

var o = new Obj();

对于1000个Obj实例,只创建了一个函数。这样可以节省999 * sizeof(M)的内存。

这是否真的是这种情况?如果是,那么以下内容属于哪个类别:

function Obj() {
    Obj.prototype.M = function() { // do something };
}
var o = new Obj();

我的直觉告诉我,在这个例子中,每次构造Obj时,原型都会被重新赋值。我不确定在这种情况下内存使用情况如何,因为将相同的函数分配给原型只会替换函数,而不是为N个实例创建N个副本。
我刚开始使用这种方法来封装成员函数的创建,但希望确保我没有做错事。

@bergi 我不确定将其标记为重复是否有意义,因为它是在链接的重复之前问的两年。 - Josh Smeaton
是的,我把“通过原型定义方法与在构造函数中使用this - 真的有性能差异吗?”视为规范的问答,所以年龄不重要。因为标题(“是否有内存性能优势?”)而找到您问题的用户应该被重定向到那里。然而,在“这是真的吗?”旁边,您实际上的问题似乎是关于第三个模式的“我想确定我没有做错事”,这实际上是一个... - Bergi
2个回答

2
function Obj() {
    Obj.prototype.M = function() { // do something };
}
var o = new Obj();

好的,正如你所猜测的那样,在创建新对象时,它将创建一个匿名函数并将其分配给原型。这是毫无意义的,而且稍微慢一点...除非你实际上在该闭包中捕获了像构造函数的参数之类的东西,否则它也是奇怪的——因为无论当前的M()是什么,它仍将与Obj的所有实例共享:

function Obj(name)
{
  Obj.prototype.M = function() { alert("Hello, " + name); }
}

var shog = new Obj("shog");
var josh = new Obj("josh");
  
shog.M(); // alerts, "Hello, josh"
josh.M(); // alerts, "Hello, josh"

如果您有好的使用方法,我很乐意听取......

另请参阅:


0
除了已经提到的内容之外,如果该闭包引用了一个局部变量(例如构造函数参数),则会出现适度的性能损失。这不仅会像前面的帖子所提到的那样很奇怪,而且还会防止被引用的变量被垃圾回收。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接