我担心我可能正在使用泄漏内存的代码模式。下面是一个伪代码示例:
window.user = new User();
user.getBasicInfo(function(basicInfo){
user.name = basicInfo.name;
user.getDetailedInfo(function(detailedInfo){
user.favoriteColor = detailedInfo.favoriteColor;
});
});
换句话说,我没有使用'this'
关键字来引用用户对象;我直接引用存储在window
对象中的user
对象。
显然,JavaScript 'this'
关键字给很多人带来了很多麻烦。我看到有些人重命名'this'
,使其更清楚,因为他们下降作用域链:
window.user = new User();
user.getBasicInfo(function(basicInfo){
var userInOuterScope = this;
userInOuterScope.name = basicInfo.name;
userInOuterScope.getDetailedInfo(function(detailedInfo){
var userInInnerScope = this;
userInInnerScope.favoriteColor = detailedInfo.favoriteColor;
});
});
不那么漂亮,但在这种情况下,作用域链似乎不那么复杂。
第一种方法会泄漏内存吗?第二个可以吗?为了避免内存泄漏,我必须将所有作为参数传递(并且永远不要引用当前作用域之外的对象)吗?
"内存泄漏"的可能性与您似乎要问的问题无关。也就是说,这两种方法对内存使用都没有影响,至少我不清楚。
您可能更愿意在代码中使用this
功能的原因是您可能需要一个对象填充。在您的例子中,您显然是将对象作为单例使用,因此没有区别。然而,这是一个特例,如果你有100个"User"对象,你很快就会发现它不能很好地工作。
保留this
的值(而不是真正的"重命名"this
;它将其值复制到闭包中的另一个变量中)可能会导致内存泄漏,或者更确切地说,可能是更大的内存泄漏设置的一部分,但它本身并没有问题。复制对象引用是经常发生的事情。
编辑本;当以下情况同时发生时,闭包的"泄漏"问题就会出现:
- 一些对象是由闭包作用域中的变量引用的(其本身并不奇怪或有害);
- 引用闭包作用域的函数从函数调用中"逃离",通过返回或通过全局状态副作用(如注册事件处理程序)导出(本身也不奇怪或有害);
- 这些导出函数的人口增长,或函数本身在调用时分配更多的空间,并保留对闭包中分配的空间的引用,或导出的函数最终由DOM节点直接引用(这在IE中特别严重)。
实际上,JavaScript没有任何具有真正闭包的语言所特有的内存泄漏问题。对于这个世界上大量的实际JavaScript软件(连接到网页的实用程序代码),内存泄漏是一个相当罕见的问题,我怀疑,尽管IE的DOM引用问题可能已经崩溃了几个浏览器多年(这可能不会让不幸的用户感到惊讶)。
我不喜欢把框架强加给人们,但是框架作者必须担心这些东西,这是绝对正确的。因此,通过确保只通过框架工具将事件处理程序和数据附加到DOM上,相信您的框架会保持DOM的干净,这是一个好主意。
似乎你的代码中没有任何循环引用,所以我不会担心内存泄漏。在我看来,你没有将对象设置为与其他对象相等(http://jsfiddle.net/Akkuma/UTL3B/作为一个快速示例,它可能导致内存泄漏)。
这里有一些关于内存泄漏的参考
- http://www.ibm.com/developerworks/web/library/wa-memleak/
- http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
- http://javascript.crockford.com/memory/leak.html
另外,你可以使用Chrome的堆快照工具来判断你是否有值得担心的内存泄漏
JavaScript的这与Java或c#的不一样。