2010-11-07 75 views
3

所以我一直在做一些JavaScript类一样的东西,如JavaScript类的内存使用情况

MyClass = function() 
{ 
    var x; 

    this.sayX = function() 
    { 
     alert(x); 
    } 
} 

,但我也看到了

MyClass = function() 
{ 
    this.x = 0; 
} 

MyClass.prototype.sayX = function() 
{ 
    alert(this.x); 
} 

最大的问题是,我还受浪费在今天的JavaScript引擎中的内存空间,还是他们能够看到我的方法中的重复并优化它们?我问的原因是我宁愿做适当的数据隐藏,也不必为'this'加上任何前缀。

+0

作为一个说明,你可以使用[用(这个){}(http://javascript.about.com/library/blwith.htm),如果它可以帮助你。 – 2010-11-07 07:02:35

+4

请勿使用“with”。使用这种软件很危险,并且将会从将来的ECAMScript实现中删除。无法强调这一点 - 假设在JavaScript中不存在“with”是好得多。 – Hamish 2010-11-07 07:14:30

+0

如果你这样做,如果你做任何继承,你需要更加小心你做什么,如何混合这两种技术,当你调用超级构造函数等等。 – 2010-11-20 02:01:16

回答

4

第一个的内存占用总是会更大。考虑将prototype作为所有实例可以使用的方法的共享包。这是有效的,因为您不为每个实例创建一个新函数,但是您正在重用已经存在于内存中的现有方法。

好消息是您展示的两种方式可以结合使用。

MyClass = function() { 
    var x; 
    // public method with access 
    // to private variables 
    this.sayX = function() { 
     alert(x); 
    }; 
} 
// method that doesn't need access to private variables 
MyClass.prototype.sharedMethod = function() { 
    // ... 
} 

但是,只要你在处理小的代码库,你不应该担心内存的使用。你甚至可以使用模式,如

// everything will be created for every 
// instance, but the whole thing is nicely 
// wrapped into one 'factory' function 
myClass = function() { 
    // private variables 
    var x; 

    // private methods 
    function doSomethingWithX() {} 

    // public interface 
    return { 
    sayX: function() { 
     alert(x); 
    }, 
    publicMethod: function() { .. }, 
    // ... 
    }; 
}; 

注意,我故意改变MyClass的小写,因为它不再是一个构造函数并没有必要调用时使用new


UPDATE - 有哪些好适合您的需要为第三图案:

MyClass = function (x, y, whatever) { 
    this._init.apply(this, arguments); 
} 

// The prototype creates a scope for data hiding. 
// It also includes a constructor function. 
MyClass.prototype = (function() { 
    var x; // private 
    return { 
    _init: function (x_in) { 
     x = x_in; 
    }, 
    sayX: function() { 
     alert(x); 
    }, 
    // ... 
    }; 
})(); 
+0

这不是严格的真(“第一个内存足迹将永远更大”)。想象一下,这种类型只有一个对象存在。虽然那么你也许可以争论第一个案件有另一个执行上下文绑定...但这甚至更好的头发:-) – 2010-11-07 09:25:33

+0

你的评论是没有建设性的。如果他只需要一个对象的实例,他就创建一个单例,而不用担心内存占用。 – galambalazs 2010-11-07 09:30:01

+0

这是非常丰富的,但它实际上并没有回答我的问题。现代JavaScript引擎能够优化这些开销吗?我可能只是建立一些测试来找出答案。 – RandomInsano 2010-11-19 23:46:01