释放 JavaScript 对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4523172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Freeing JavaScript object
提问by pion
I am looking at the example from http://www.javascriptkit.com/javatutors/oopjs.shtml
我正在查看http://www.javascriptkit.com/javatutors/oopjs.shtml中的示例
var person = new Object()
person.name = "Tim Scarfe"
person.height = "6Ft"
But there is no mention how to "free" it in order to avoid memory leak.
但是没有提到如何“释放”它以避免内存泄漏。
Will the following code free it?
下面的代码会释放它吗?
person = null;
- How do you free a JavaScript Object using "new Object()?
- How do you free a JavaScript Array allocated using "new Array(10)"?
- How do you free a JavaScript JSON allocated using "var json = {"width": 480, "height": 640}"?
- 如何使用“new Object() 释放 JavaScript 对象?
- 如何释放使用“new Array(10)”分配的 JavaScript 数组?
- 如何释放使用“var json = {“width”:480,“height”:640}”分配的JavaScript JSON?
Thanks in advance for your help.
在此先感谢您的帮助。
回答by T.J. Crowder
You don't have to explicitly "free" JavaScript objects. JavaScript is a garbage-collected language.
您不必明确“释放” JavaScript 对象。JavaScript 是一种垃圾收集语言。
What you cando is ensure that nothing is referencingmemory you're not using any more, since memory that is being referenced cannot be released. Nearly all of the time, that happens automatically. For instance:
您可以做的是确保没有任何内容引用您不再使用的内存,因为无法释放正在引用的内存。几乎所有的时间,这都是自动发生的。例如:
function foo() {
var a = [1, 2, 3, 4, 5, 6];
// Do something
}
The memory allocated to the array apointed to is eligible to be reclaimed once fooreturns, because it's no longer referenced by anything (ahaving gone out of scope with nothing having an outstanding reference to it).
分配给a指向的数组的内存在foo返回后有资格被回收,因为它不再被任何东西引用(a已经超出了范围,没有任何对它的未完成引用)。
In contrast:
相比之下:
function foo() {
var a = [1, 2, 3, 4, 5, 6];
document.getElementById('foo').onclick = function() {
alert("You clicked foo!");
};
}
Now, the memory that apoints to cannot be reclaimed, because there's a closure (the event handler function) that has an active reference to it, and there's something keeping the closure in memory (the DOM element). (Yes, the closure has a reference to a[an indirect one] even though adoesn't appear anywhere in the closure; details on how closures work and their effect on garbage collection here in Closures are not complicated.) If I know that array isn't going to be used, I can release the memory for the array:
现在,a指向的内存无法回收,因为有一个闭包(事件处理函数)对它有一个活动引用,并且有一些东西将闭包保留在内存中(DOM 元素)。(是的,a即使a没有出现在闭包中的任何地方,闭包也有对[间接引用]的引用;关于闭包如何工作及其对Closures 中垃圾收集的影响的详细信息并不复杂。)如果我知道该数组是不会被使用,我可以释放数组的内存:
function foo() {
var a = [1, 2, 3, 4, 5, 6];
document.getElementById('foo').onclick = function() {
alert("You clicked foo!");
};
a = undefined;
}
Now, although astill exists, it no longer refers to the array, so the array's memory can be reclaimed.
现在,虽然a仍然存在,但它不再引用数组,因此可以回收数组的内存。
More in this other answer here on StackOverflow.
Update: I probably should have mentioned delete, although it doesn't apply to the precise code in your question.
更新:我可能应该提到delete,尽管它不适用于您问题中的确切代码。
If you're used to some other languages, you might think "Ah, deleteis the counterpart to new" but in fact the two have absolutely nothingto do with one another.
如果你习惯了其他一些语言,你可能会认为“啊,delete是”的对应物,new但实际上两者完全没有关系。
deleteis used to remove properties from objects. It doesn't apply to your code sample for the simple reason that you can't delete vars. But that doesn't mean that it doesn't relate to other code you might run across.
delete用于从对象中删除属性。它不适用于您的代码示例,原因很简单,您无法删除vars。但这并不意味着它与您可能遇到的其他代码无关。
Let's consider two bits of code that seem to do largely the same thing:
让我们考虑一下似乎做着大致相同的事情的两段代码:
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`
vs.
对比
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
Both of those make the memory that propwas pointing to eligible for garbage collection, but there's a difference: In the first example, we haven't removed the property, but we've set its value to undefined. In the second example, we've completely removed the property from the object. This is not a distinction without a difference:
这两者都使prop指向的内存符合垃圾收集条件,但有一个区别:在第一个示例中,我们没有删除该属性,但我们已将其值设置为undefined。在第二个示例中,我们已从对象中完全删除了该属性。这不是没有区别的区别:
alert("prop" in a); // "true"
alert("prop" in b); // "false"
But this applies to your question in the sense that deleting a property means any memory that property was pointing to becomes available for reclamation.
但这适用于您的问题,因为删除属性意味着该属性指向的任何内存都可用于回收。
So why doesn't deleteapply to your code? Because your personis:
那么为什么delete不适用于您的代码呢?因为你person是:
var person;
Variables declared with varareproperties of an object, but they cannot be deleted. ("They're properties of an object?" I hear you say. Yes. If you have a varat global scope, it becomes a property of the global object [window, in browsers]. If you have a varat function scope, it becomes a property of an invisible — but very real — object called a "variable object" that's used for that call to that function. Either way, though, you can't delete 'em. More about that in the link aboveabout closures.)
用 with 声明的变量var是对象的属性,但它们不能是deleted。(“它们是对象的属性?”我听到你说。是的。如果你有一个varat 全局范围,它就会成为全局对象的一个属性 [ window,在浏览器中]。如果你有一个varat 函数范围,它就会变成一个不可见但非常真实的对象的属性,称为“变量对象”,用于调用该函数。但是,无论哪种方式,你都不能删除它们。更多关于上面关于闭包的链接。)
回答by Jacob Relkin
JavaScript does this all for you, but if you want to explicitly free an object or variable, then yes, setting it to nullis the closest you can get to doing this.
JavaScript 为您完成了这一切,但是如果您想显式释放一个对象或变量,那么是的,将其设置null为最接近您可以做到的。

