重命名'this'关键字

Renaming the 'this' keyword

本文关键字:关键字 this 重命名      更新时间:2023-09-26

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

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;它将其值复制到闭包中的另一个变量中)可能会导致内存泄漏,或者更确切地说,可能是更大的内存泄漏设置的一部分,但它本身并没有问题。复制对象引用是经常发生的事情。

编辑本;当以下情况同时发生时,闭包的"泄漏"问题就会出现:

  1. 一些对象是由闭包作用域中的变量引用的(其本身并不奇怪或有害);
  2. 引用闭包作用域的函数从函数调用中"逃离",通过返回或通过全局状态副作用(如注册事件处理程序)导出(本身也不奇怪或有害);
  3. 这些导出函数的人口增长,函数本身在调用时分配更多的空间,并保留对闭包中分配的空间的引用,导出的函数最终由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#的不一样。