释放JavaScript对象
我正在看来自 但没有提到如何“释放”它以避免内存泄漏 下面的代码会释放它吗释放JavaScript对象,javascript,Javascript,我正在看来自 但没有提到如何“释放”它以避免内存泄漏 下面的代码会释放它吗 person = null; 如何使用“newobject()”释放JavaScript对象 如何释放使用“新数组(10)”分配的JavaScript数组 如何释放使用“var JSON={“width”:480,“height”:640}”分配的JavaScript JSON 提前感谢您的帮助。JavaScript可以帮您完成这一切,但是如果您想显式释放对象或变量,那么是的,将其设置为null是最接近的方法。您不必显
person = null;
提前感谢您的帮助。JavaScript可以帮您完成这一切,但是如果您想显式释放对象或变量,那么是的,将其设置为
null
是最接近的方法。您不必显式地“释放”“JavaScript对象。所有标准JavaScript主机/环境都根据对象是否可以访问而使用垃圾收集。(可能有一些小型主机,比如一些用于嵌入式系统的主机,它们不会这样做;如果是这样,它们将提供自己的显式释放方式。)如果无法再访问该对象,则可以回收该对象的内存
您可以做的是确保没有任何内容引用您不再使用的内存,因为被引用的内存无法释放。几乎所有的时候,这都是自动发生的。例如:
function foo() {
var a = [1, 2, 3, 4, 5, 6];
// Do something
}
分配给指向的数组a
的内存有资格在foo
返回后被回收,因为它不再被任何东西引用(a
超出范围,没有任何东西对它有未完成的引用)
相比之下:
function foo() {
var a = [1, 2, 3, 4, 5, 6];
document.getElementById("foo").addEventListener("click", function() {
alert("a.length is " + a.length);
});
}
现在,a
指向的内存无法回收,因为有一个闭包(事件处理程序函数)具有对它的活动引用,并且有一些东西将闭包保存在内存中(DOM元素)
您可能会认为,只有在上述情况下,闭包明确使用了a
,这才重要,但在这里,闭包不使用a的情况下,这并不重要:
function foo() {
var a = [1, 2, 3, 4, 5, 6];
document.getElementById("foo").addEventListener("click", function() {
alert("You clicked foo!");
});
}
但是,根据规范
保留一个,即使闭包不使用它,闭包仍然有一个对它的间接引用。(在我的[相当老的]博客文章中有更多)有时候JavaScript引擎可以优化a
,尽管早期的积极尝试被退回了——至少在V8中是这样——因为执行该操作所需的分析影响了性能,而不仅仅是让数组留在内存中
如果我知道闭包不会使用数组,我可以通过为a
指定不同的值来确保数组不会被引用:
function foo() {
var a = [1, 2, 3, 4, 5, 6];
document.getElementById("foo").addEventListener("click", function() {
alert("You clicked foo!");
});
a = undefined; // <===============
}
vs
这两个属性都使prop
指向的内存符合垃圾收集的条件,但有一点不同:在第一个示例中,我们没有删除该属性,但是我们将其值设置为未定义的。在第二个示例中,我们已经从对象中完全删除了属性。这不是没有区别的区别:
alert("prop" in a); // "true"
alert("prop" in b); // "false"
但这适用于您的问题,因为删除属性意味着该属性指向的任何内存都可用于回收
那么为什么delete
不适用于您的代码呢?因为你的人
是:
var person;
用var
声明的变量是对象的属性,但不能是delete
d。(“它们是对象的属性?”我听到你说。是的。如果在全局范围内有一个var
,它就会成为全局对象的属性[window
,在浏览器中)。如果在函数范围内有一个var
,它就会成为一个不可见但非常真实的对象的属性,称为“变量对象”这是用来调用该函数的。不过,无论哪种方式,都不能删除它们。关于闭包的更多信息。)这不是JavaScript JSON。它只是对象文字符号。只有当它是字符串时才是JSON。另请参见:脱离主题:您从该站点获得的示例代码不是很好。1. <代码>新对象()
=>{}
;2.它依赖于自动插入分号,如果不是魔鬼的后代,它仍然是你绝对不应该依赖的东西;3.好吧,这一点并不可怕,但是嘿,为什么不教文字符号呢<代码>var person={姓名:“Tim Scarfe”,身高:“6英尺”}代码>但实际上是#2和#1(在较小程度上)使我成为“blech”+1,用于指出范围链和隐藏的“绑定”。我想知道是否有任何JS引擎足够聪明,能够自动消除上述情况——无论如何,只有嵌套范围中的“eval”或显式用法才能访问绑定(从代码)。谢谢您的帮助。“a=null;”是否与“a=undefined;”相同?@pion:Will“a=null;”是否与“a=undefined;”相同?为了释放a
指向的任何其他内存,是。我使用undefined
,因为这是未初始化的属性(和变量)的值,所以我认为undefined
(而不是null
)是属性的“空白”状态。但是null
也很好,您可以看到它被大量使用。:-)@pst:“我想知道是否有任何JS引擎足够聪明,能够自动消除上述情况”如果V8还没有使用没有引用或eval
的代码(或者更好,使用严格的代码),我打赌在某个时候会这样做。或者如果没有,你肯定有一个很好的理由我们没有看到。:-)@Phrogz,你不能删除变量,只能删除属性。尝试运行这个(在页面中的脚本中,而不是在Firebug/WebKit控制台中运行):var a='test',b={c:'test'};console.log('a:',a);log('deletea:',deletea);console.log('a:',a);console.log('b.c:',b.c.);log('delete b.c:',delete b.c.);console.log('b.c:',b.c.)代码>然后读:Phah。我确信你不能删除变量,然后我看到另一个答案,我很懒,只在控制台中测试它。多么尴尬啊!)如果计时器不响,我会修正我的谎言,所以我会杀了c
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
alert("prop" in a); // "true"
alert("prop" in b); // "false"
var person;