在Javascript中对同一个变量没有`删除`的`new`

时间:2011-02-02 00:53:36

标签: javascript object garbage-collection new-operator

这样做可以吗?:

function mygetTime()
{
    var d = new Date();
    return(d.getTime());
}

function wasteSomeMemory()
{
    var temp;
    for(var count = 0; count < 1000000; count += 1)
    {
        temp = mygetTime();
    }
}

调用wasteSomeMemory()会导致内存泄漏吗?

这个怎么样:

function wasteSomeMemory2()
{
    var temp;
    for(var count = 0; count < 1000000; count += 1)
    {
        temp = new Date();
    }
}

调用wasteSomeMemory2()会导致内存泄漏吗?我应该在for循环结束时使用delete temp;吗?

function wasteSomeMemory2()
{
    var temp;
    for(var count = 0; count < 1000000; count += 1)
    {
        temp = new Date();
        delete temp;
    }
}

2 个答案:

答案 0 :(得分:30)

newdelete在JavaScript中没有任何关系(尽管它们与其他语言中完全不同的构造有着令人困惑的相似性)。不要担心创建对象(new)而不明确地清理它们,这就是垃圾收集器的工作。

new用于通过构造函数创建对象。另一方面,delete用于从对象中删除属性。除了作为副作用之外(例如,如果对该对象的唯一未完成引用来自您删除的属性),它与从内存中删除对象有 nothing

正确使用delete

的示例
var obj = {};
obj.foo = "bar"; // Now `obj` has a property called `foo`
delete obj.foo;  // Now it doesn't

您的getmyTime功能非常好。函数返回后,Date对象将有资格立即回收( 回收的对象完全取决于实现)。除了有缺陷的实现之外,它不会导致内存泄漏。

您的wasteSomeMemory2同样不会导致内存泄漏,实际上您无法调用delete temp; - 您只能删除属性,而不能删除变量。


当你必须帮助垃圾收集器时次,但那些通常不会(根据我的经验)与对象属性有关,所以不要涉及{{1} }。当你创建函数实例时,它们才会真正出现(如果你正在设置事件处理程序或计时器函数等,这通常很常见)。例如,考虑:

delete

因为您通过function foo() { var listOfThings = /* ...get a list of things... */; // ...do something with `listOfThings`... setInterval(function() { // ...do something that *doesn't* need `listOfThings`... }, 1000); } 分配给计时器的匿名函数将在函数调用中继续存在,所以它会保留对该函数调用期间范围内所有内容的实时引用(无论是否使用它) 。这样可以保留setInterval指向内存的内容列表。如果计时器功能不需要该列表,那么这是一个问题。如果您知道该功能不需要,可以发布listOfThings指向的列表,方法是在listOfThingsundefined时为null分配listOfThings完成它:

function foo() {

    var listOfThings = /* ...get a list of things... */;

    // ...do something with `listOfThings`...

    listOfThings = undefined; // Done with it           <== The new bit

    setInterval(function() {
       // ...do something that *doesn't* need `listOfThings`...
    }, 1000);
}

对于事件处理函数等也是如此。无论何时创建函数,它都会“关闭”(保持实时引用)范围内定义的任何内容。因此,如果您不需要这些东西,您可以通过清除它们的引用来确保它们不会留在内存中。 (更多:Closures are not complicated

答案 1 :(得分:4)

简短的回答是否定的。

长期的答案是我们希望上帝浏览垃圾收集器。