当不再需要变量时,将其设置为null是一种好的做法吗?

39

我曾经看到过在函数末尾将 JavaScript 值设置为 null 的情况。这是为了 减少内存使用 还是为了 防止其他地方意外使用

这样做是否有好处?如果有,那么什么情况下需要这样做?

var myValue;
.
.
.
myValue = null;

有没有将变量设置为null或使用delete来提高性能或优化内存使用的情况? - bob
在某些罕见情况下,您可能希望将null设置为变量或对象属性,以允许GC释放内存(设置为null并不意味着内存会立即被释放)。假设您有一个SPA,它积极使用缓存来存储一些html数据。保存缓存的变量可以从闭包中访问,该闭包将在整个运行时间内存在。也许您在应用程序的某个状态下不再需要它了,因此请将其标记为空。 - Kirill Reznikov
但我相信通常这种情况是由于糟糕的应用程序设计所导致的。 - Kirill Reznikov
4个回答

21

在函数的结尾处将本地变量设置为null并不会产生任何影响,因为它在返回时就会从堆栈中移除。

然而,在闭包内部,该变量将不会被释放。

var fn = function() {

   var local = 0;

   return function() {
      console.log(++local);
   }

}

var returned = fn();

returned(); // 1
returned(); // 2

jsFiddle

当内部函数被返回时,外部变量的作用域将继续存在,并可以被返回的内部函数访问。


在函数结束时将其设置为 null 是多余的吗? - bob
1
除非变量未使用“var”声明,否则请返回已翻译的文本。 - bob
1
@bob...并且该变量不是函数内部的局部变量。 - fireshadow52
1
在IE中,与变量引用DOM元素相关的一些特定问题可能会出现。以jQuery源代码中的这段代码为例,其中有许多此类变量被设置为null - user113716
1
你考虑过闭包吗? - RobG

20

iE存在一个问题,涉及DOM元素的循环引用。通常在以下情况下会出现这种问题:当附加监听器时:

function doStuff() {
   var el = document.getElementById('someID');
   el.onclick = function() {
     // has closure to el
   };

   // remove reference to element
   el = null;
}

当调用doStuff时,附加到元素的匿名函数会将闭包返回到元素 - 形成了一个循环引用。在旧版IE中,这会导致内存泄漏,因此解决方法是在分配给el.onclick后将el设置为null(或除el之外的任何内容),以断开循环引用。

使用它的第二个原因类似-如果函数具有保留对可能被垃圾回收的大对象的引用的闭包,则删除引用可能很有用,以便可以清理该对象:

var someFunction = (function() {
  var x = reallyBigObject;
  // do stuff that uses reallyBigObject

  // Remove reference to reallyBigObject if it's no longer required
  x = null;

  return function() {
    // closure to x is unavoidable, but reference to reallyBigObject isn't required
  }
}());

因此,如果返回给someFunction的函数实际上不需要引用reallyBigObject,那么可以删除该引用,以便闭包不会阻止它被不必要地垃圾回收。

请注意,您无法防止闭包对作用域内的变量进行引用,但是您可以修改它们的值。

除非您长时间保留页面并执行大量AJAX操作以及添加和删除大量DOM节点,否则通常不会出现此类问题。但最好养成在不需要时从闭包中删除对象引用的习惯。


在你的第二个例子中,你需要使用第二个带有 xvar 吗? - alex
如果在执行“x = null;”这行代码之前返回任何内容,那么你将永远无法到达那行代码。 - AntouanK
啊,是的,我的疏忽。 - RobG

3

不,它并不是。每个本地变量在函数结束后都会被删除。


1
我不知道为什么有人踩了我的回答,而我的回答是正确的。请在评论中指出我的错误之处。 - avall
因为我们在这里通常谈论的是将其分配给null,问题中也没有提到局部变量或全局变量。 - nikoss
1
@bob 写道“在函数的末尾”,所以我认为这个问题是关于局部变量的。被接受的答案几乎是用其他的话说了同样的意思。请理解阅读。哦,你现在也给它点了踩吗? - avall

-2

非常是的。

特别是当变量包含一些秘密信息,例如返回的密码时。

一旦使用变量,请将其声明为null或"",因为js中的活动变量可以通过检查元素来读取。

var password = $('#password').val();

在评估变量密码后,将其重置为“”。如果您不这样做,则可以通过选择任何现有的HTML项(例如按钮)并使用检查元素来添加属性代码来访问该值。

onclick = "javascript:alert(password);"

将变量密码重置为null将保持您的密码信息安全。
var password = $('#password').val();
//do what you want to do with variable password
password = null;

6
你可以在浏览器内置的调试器中随时查看 JavaScript 中任何变量的值。 - octothorpentine

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