释放JavaScript对象

pio*_*ion 18 javascript

我正在查看来自http://www.javascriptkit.com/javatutors/oopjs.shtml的示例

var person = new Object()
person.name = "Tim Scarfe"
person.height = "6Ft"
Run Code Online (Sandbox Code Playgroud)

但是没有提到如何"释放"它以避免内存泄漏.

以下代码会免费吗?

person = null;
Run Code Online (Sandbox Code Playgroud)
  1. 如何使用"new Object()释放JavaScript对象?
  2. 如何释放使用"new Array(10)"分配的JavaScript数组?
  3. 如何释放使用"var json = {"width":480,"height":640}分配的JavaScript JSON"?

在此先感谢您的帮助.

T.J*_*der 50

您不必明确"释放"JavaScript对象.JavaScript是一种垃圾收集语言.

可以做的是确保没有任何内容引用您不再使用的内存,因为无法释放正在引用的内存.几乎所有的时间都会自动发生.例如:

function foo() {
   var a = [1, 2, 3, 4, 5, 6];

   // Do something
}
Run Code Online (Sandbox Code Playgroud)

分配给a指向的数组的内存有资格在foo返回后被回收,因为它不再被任何东西引用(a超出范围,没有任何具有未完成引用的内容).

相反:

function foo() {
   var a = [1, 2, 3, 4, 5, 6];

   document.getElementById('foo').onclick = function() {
       alert("You clicked foo!");
   };
}
Run Code Online (Sandbox Code Playgroud)

现在,a指向的内存无法回收,因为有一个闭包(事件处理函数),它有一个活动的引用,并且有一些东西将闭包保留在内存中(DOM元素).(是的,闭包引用了a[间接的],即使a没有出现在闭包中的任何地方;关闭如何工作以及它们在闭包中对垃圾收集的影响的细节并不复杂.)如果我知道数组不是不会被使用,我可以释放阵列的内存:

function foo() {
   var a = [1, 2, 3, 4, 5, 6];

   document.getElementById('foo').onclick = function() {
       alert("You clicked foo!");
   };

   a = undefined;
}
Run Code Online (Sandbox Code Playgroud)

现在,虽然a仍然存在,但它不再引用数组,因此可以回收数组的内存.

更多关于StackOverflow的其他答案.


更新:我可能应该提到delete,虽然它不适用于你问题中的精确代码.

如果你习惯了其他一些语言,你可能会认为"啊,delete是对应的new",但实际上这两种语言完全没有关系.

delete用于从对象中删除属性.它不适用于您的代码示例,原因很简单,您无法删除vars.但这并不意味着它与您可能遇到的其他代码无关.

让我们考虑一下看起来大致相同的两位代码:

var a = {};         // {} is the same as new Object()
a.prop = "foo";     // Now `a` has a property called `prop`, with the value "foo"
a.prop = undefined; // Now `a` has a property called `prop`, with the value `undefined`
Run Code Online (Sandbox Code Playgroud)

var b = {};         // Another blank object
b.prop = "foo";     // Now `b` has a property called `prop`, with the value "foo"
delete b.prop;      // Now `b` has *NO* property called `prop`, at all
Run Code Online (Sandbox Code Playgroud)

这两个都使得prop指向符合垃圾收集条件的内存,但是有区别:在第一个示例中,我们没有删除该属性,但我们已将其值设置为undefined.在第二个示例中,我们已从对象中完全删除了该属性.这不是没有区别的区别:

alert("prop" in a); // "true"
alert("prop" in b); // "false"
Run Code Online (Sandbox Code Playgroud)

但这适用于您的问题,因为删除属性意味着属性指向的任何内存都可用于回收.

那么为什么delete不适用于您的代码?因为你person是:

var person;
Run Code Online (Sandbox Code Playgroud)

声明的变量var 对象的属性,但它们不能是deleted.("它们是对象的属性?"我听到你说.是的.如果你有一个var全局范围,它就成了全局对象的一个​​属性[ window,在浏览器中].如果你有一个varat函数范围,它就变成了一个不可见但非常真实的对象,称为"变量对象",用于对该函数的调用.但是,无论哪种方式,你都不能删除它们.关于闭包的上述链接更多信息.)

  • @pion:*将“ a = null;” 和“ a = undefined;” *一样吗?为了释放任何其他内存,“ a”指向的是。我使用undefined,因为这是未初始化的值属性(和变量),因此我认为undefined(而不是null)是属性的“空白”状态。但是`null'也很好,您会发现它使用了很多。:-) (2认同)