重命名'this'关键字

时间:2011-07-14 14:14:57

标签: javascript memory-leaks scope closures

我担心我可能会使用泄漏内存的代码模式。这是一个伪代码示例:

window.user = new User(); 

user.getBasicInfo(function(basicInfo){

  user.name = basicInfo.name;

  user.getDetailedInfo(function(detailedInfo){

    user.favoriteColor = detailedInfo.favoriteColor;

  });

});

换句话说,我没有使用'this'关键字来引用用户对象;我直接引用user对象中存储的window对象。

显然,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;

  });

});

不是很漂亮,但在这种情况下,似乎范围链可能不那么复杂。

第一种方法可以泄漏内存吗?第二个可以吗?为了避免泄漏内存,我必须将所有内容作为参数传递(并且永远不要引用当前范围之外的对象)吗?

3 个答案:

答案 0 :(得分:4)

“泄漏记忆”的可能性与您似乎要问的问题无关。也就是说,这两种方法都没有对内存使用产生影响,至少对我来说并不是很清楚。

您可能更喜欢在代码中使用this工具的原因是您可能需要一组对象。在你的情况下,你显然使用对象作为单身,所以没有区别。但是,这确实是一个特例,如果你有100个“用户”对象,你会很快发现它不能很好地工作。

保留this的值(并且它不是真正“重命名”this;它正在将其值复制到另一个变量中)在闭包内可能导致内存泄漏或者更确切地说,可能是更大的内存泄漏设置的一部分,但它本身并没有问题。制作对象引用的副本是一直在发生的事情。

编辑 - 当一系列事情发生时,关闭会出现“泄漏”问题:

  1. 某些对象由闭包范围中的变量引用(本身并不奇怪或有害);
  2. 通过返回或通过全局状态副作用(如注册事件处理程序)导出,从函数调用中引用闭包作用域“escape”的函数(也不是奇怪或有害的) ;
  3. 这些导出函数的数量增长,函数本身在调用时会分配更多空间,并保留对闭包中分配的空间的引用,导出的函数最终由DOM节点直接引用(这在IE中尤其是一个问题)。
  4. 实际上,JavaScript没有任何内存泄漏的独特问题,任何具有真正闭包的语言都有。对于这个世界上的大量实际JavaScript软件(连接到网页的实用程序代码),我怀疑内存泄漏是一个问题非常罕见,尽管DOM引用的IE问题多年来可能已经崩溃了几个浏览器(这可能不会让倒霉的用户感到惊讶。)

    我不喜欢在人们身上推送框架,但框架作者必须担心这些东西。因此,通过确保只通过框架工具将事件处理程序和数据附加到DOM来信任您的框架以保持DOM清洁是一个好主意。

答案 1 :(得分:1)

您的代码中似乎没有任何循环引用,因此我不担心内存泄漏。就我所见,你不是将对象设置为等于其他对象(http://jsfiddle.net/Akkuma/UTL3B/作为一个快速示例,它可能导致内存泄漏)。

以下是关于内存泄漏的一些参考资料

此外,您可以使用Chrome的堆快照工具来判断您是否有值得担心的内存泄漏。

答案 2 :(得分:0)

JavaScript这与Java或C#不同。它代表了正在执行的事物的当前背景。