释放JavaScript对象 [英] Freeing JavaScript object

查看:37
本文介绍了释放JavaScript对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看 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.

以下代码会释放它吗?

person = null;

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

预先感谢您的帮助.

推荐答案

您不必显式地免费"JavaScript对象.所有标准的JavaScript主机/环境都会根据是否可以访问该对象来使用垃圾回收.(可能有一些合适的主机,例如嵌入式系统中的某些主机;如果没有,它们将提供自己的显式释放对象的方法.)如果无法再访问该对象,则可以为其存储回收.

You don't have to explicitly "free" JavaScript objects. All standard JavaScript hosts/environments use garbage collection based on whether the object can be reached anymore. (There may be niche hosts, such as some for embedded systems, that don't; they'll supply their own means of explicitly releasing things if so.) If the object can't be reached anymore, the memory for it can be reclaimed.

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

What you can do is ensure that nothing is referencing memory 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
}

分配给数组 a 的内存有资格在 foo 返回时回收,因为它不再被任何东西引用( a 已超出范围,没有任何内容对其有很好的引用.

The memory allocated to the array a pointed to is eligible to be reclaimed once foo returns, because it's no longer referenced by anything (a having gone out of scope with nothing having an outstanding reference to it).

相反:

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

   document.getElementById("foo").addEventListener("click", function() {
       alert("a.length is " + a.length);
   });
}

现在,无法回收 a 指向的内存,因为有一个闭包(事件处理函数)对其有有效的引用,并且有些东西将闭包保留在内存中(DOM元素.)

Now, the memory that a points 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).

您可能会认为这仅在上面重要,因为闭包显然使用了 a ,但在这里不重要的地方无关紧要:

You might think that only matters in the above, where the closure clearly uses a, but wouldn't matter here where it doesn't:

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

   document.getElementById("foo").addEventListener("click", function() {
       alert("You clicked foo!");
   });
}

但是,即使规范不使用闭包,按规范 a 也会保留,闭包仍具有对其的间接引用.(有关更多信息,请访问我的[相当老的]博客文章 关闭并不复杂 .)有时 JavaScript引擎可以优化 a ,尽管早期的积极努力已回滚了-至少在V8中—因为进行分析所需的性能影响不只是将阵列留在内存中,而是对性能的影响更大.

But, per specification a is retained even if the closure doesn't use it, the closure still has an indirect reference to it. (More in my [fairly old] blog post Closures Are Not Complicated.) Sometimes JavaScript engines can optimize a away, though early aggressive efforts to do it were rolled back — at least in V8 — because the analysis required to do it impacted performance more than just having the array stay in memory did.

如果我知道闭包将不使用该数组,则可以通过为 a 分配一个不同的值来确保不引用该数组:

If I know that array isn't going to be used by the closure, I can ensure that the array isn't referenced by assigning a different value to a:

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

   document.getElementById("foo").addEventListener("click", function() {
       alert("You clicked foo!");
   });

   a = undefined; // <===============
}

现在,尽管 a (变量)仍然存在,但是它不再引用数组,因此可以回收数组的内存.

Now, although a (the variable) still exists, it no longer refers to the array, so the array's memory can be reclaimed.

有关此处的其他答案,请参见StackOverflow .

更新:我可能应该提到 delete ,尽管它不适用于您问题中的确切代码.

Update: I probably should have mentioned delete, although it doesn't apply to the precise code in your question.

如果您习惯了其他一些语言,您可能会认为啊,删除 new 的对应语言".但实际上,两者绝对没有任何关系.

If you're used to some other languages, you might think "Ah, delete is the counterpart to new" but in fact the two have absolutely nothing to do with one another.

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

delete is 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.

让我们考虑似乎在很大程度上做相同事情的两段代码:

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

这两个都使 prop 指向的内存可以进行垃圾回收,但是有一个区别:在第一个示例中,我们没有删除该属性,但是我们设置了它值为 undefined .在第二个示例中,我们已经从对象中完全删除了该属性.这是没有区别的区别:

Both of those make the memory that prop was 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:

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.

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

So why doesn't delete apply to your code? Because your person is:

var person;

var 声明的变量是对象的属性,但不能被 delete 删除.(它们是对象的属性吗?"我听你说.是的.如果您在全局范围内具有 var ,它将成为全局对象[ window (在浏览器中).如果您在函数作用域中有一个 var ,它将成为一个不可见(但非常真实)的对象的属性,该对象称为变量对象",用于对该对象的调用无论哪种方式,您都无法删除'em.有关此内容的更多信息,请参见上面关于闭包的链接.

Variables declared with var are properties of an object, but they cannot be deleted. ("They're properties of an object?" I hear you say. Yes. If you have a var at global scope, it becomes a property of the global object [window, in browsers]. If you have a var at 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 above about closures.)

这篇关于释放JavaScript对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆