重复变量会导致内存泄漏吗?

时间:2011-08-22 16:45:20

标签: javascript

在设置全局变量和局部变量时,我已经了解了内存泄漏以及如何避免它们。我还是有点困惑。

我们只是说这些例子发生在页面深处,其中使用了其他全局变量和局部变量。

如果我不打算重复使用变量,我应该还是不应该使用var

如果我在函数中使用var一次,在操作或修改变量时是否需要再次使用它?

// EMAMPLE ONE
$("#AddBrandSave").click(function() {
    // DO THIS?
    Brand = $("#Brand").val();
    // OR DO THIS?
    var Brand = $("#Brand").val();
});

// EMAMPLE TWO
$("#AddBrandSave").click(function() {
    // DO THIS?
    Brand = $("#Brand").val();
    Brand = Brand.substring(7); 
    Brand = Brand.someMathFunction(); 
    // OR DO THIS?
    var Brand = $("#Brand").val();
    Brand = Brand.substring(7); 
    Brand = Brand.someMathFunction; 
    // OR DO THIS?
    var Brand = $("#Brand").val();
    var Brand = Brand.substring(7); 
    var Brand = Brand.someMathFunction(); 
});

3 个答案:

答案 0 :(得分:4)

了解var

Javascript有两个级别的范围,全局和功能。当您使用var时,该变量的声明将被提升到它所在范围的顶部。例如:

$("#AddBrandSave").click(function() {
    var Brand = $("#Brand").val();
    var Brand = Brand.substring(7); 
    var Brand = Brand.someMathFunction(); 
});

被解释为

$("#AddBrandSave").click(function() {
    var Brand;    
    Brand = $("#Brand").val();
    Brand = Brand.substring(7); 
    Brand = Brand.someMathFunction(); 
});

如果你没有在函数中包含var,那么“Brand”将在全局范围内声明,所以

$("#AddBrandSave").click(function() {
    Brand = $("#Brand").val();
    Brand = Brand.substring(7); 
    Brand = Brand.someMathFunction(); 
});

被解释为:

var Brand; 
$("#AddBrandSave").click(function() { 
    Brand = $("#Brand").val();
    Brand = Brand.substring(7); 
    Brand = Brand.someMathFunction(); 
});
// The global variable Brand will only exist after #AddBrandSave is clicked
// or it will clobber the global variable Brand if it already existed

这就是为什么建议您在该函数顶部的var函数中声明要使用的任何变量,因为无论如何技术上都是这样,因此它更容易理解。< / p>

对同一个变量多次使用var可能会导致问题,因为它会使解释器工作更难以检查该变量是否已存在 - 我不知道它是否会导致内存泄漏,但为什么会冒这个风险呢? ?

答案 1 :(得分:2)

问题实际上是变量正确性之一:

在JavaScript中,如果您未在函数中使用var,则假定该变量是全局变量,并且您在该名称下可能拥有的任何实际全局变量将被静默破坏

在大多数情况下,您希望使用var。多次使用它没有任何效果(甚至可能是一个错误)。所以你想要在每个例子中使用第二种方法。

答案 2 :(得分:2)

当您创建/使用变量时,您应首先确定是否希望该变量是全局变量(程序中的所有位置都可用且值永远持续)或局部变量(此变量仅存在于当前函数内)范围并将在函数范围完成时销毁。)

一般来说,你希望一切都是一个局部变量(因为这是更安全和更好的开发实践),除非你绝对必须使它全局化。

因此,一旦你弄清楚你是想将变量变为局部变量还是全局变量,你就可以决定如何使用变量。

对于局部变量,你应该在第一次在函数中定义时使用var声明它,然后在函数中没有其他时间。

对于全局变量,您应该在函数外部使用var声明它,然后在函数内部使用var而不使用var。如果你在函数中使用它而没有在任何地方用var声明它,你将隐含地声明并使用一个通常不是一个好习惯的全局变量,因为每个人都不容易看到你的意图是什么并且很容易意外地制作一个错误。

一些例子:

声明,然后使用名为“i”的局部变量:

// here the variable i is declared separately as a local variable
function findIndex(array, val) {
    var i;
    for (i = 0; i < array.length; i++) {
        if (array[i] === val) {
            return(i);
        } 
    }
    return(-1);
}

// here the variable i is declared at first use as a local variable
function findIndex(array, val) {
    for (var i = 0; i < array.length; i++) {
        if (array[i] === val) {
            return(i);
        } 
    }
    return(-1);
}

显式全局变量“i”:

// declaring i globally outside the scope of any function
var i;

// here the variable i is declared at first use as a local variable
function findIndex(array, val) {
    for (i = 0; i < array.length; i++) {
        if (array[i] === val) {
            return(i);
        } 
    }
    return(-1);
}

隐含的全局变量“i”(坏主意):

// here the variable i is not declared at first use as a local variable and
// thus becomes a global variable (an implicit global declaration)
function findIndex(array, val) {
    for (i = 0; i < array.length; i++) {
        if (array[i] === val) {
            return(i);
        } 
    }
    return(-1);
}

使用全局变量时,必须注意它们可能会使用同名的全局变量与其他代码冲突。关于如何保护全局变量以减少冲突的可能性,有一个完全独立的讨论。如果您想了解更多相关信息,请搜索“javascript命名空间”。但是,一般情况下,除非必须使用全局变量,否则不应该使用全局变量,您应该在命名空间中保护它,或者给它提供非常非常独特的名称,这个名称不可能与其他任何有助于其他人的名称冲突。您的项目(或您使用的任何库)正在使用。

至于你关于内存泄漏的问题。全局或局部变量以一种特定方式与内存泄漏相关。 Javascript和浏览器DOM是垃圾收集环境。这意味着当DOM或Javascript变量中对这些对象的引用更长时,它们会释放对象。因此,如果从DOM中删除一个对象并且在代码中没有对该对象的任何引用,那么它的内存将被释放。

另一方面,如果你在全局变量中引用了该对象(全局变量永远存在),那么即使你从DOM中删除该对象或者在javascript中使用该对象完成,也是如此由于全局变量包含对该对象的引用,因此垃圾收集器无法释放其内存。在函数完成时销毁的局部变量没有这个问题,因为它们对事物的引用通常会被自动销毁(在函数闭包中有一些例外),所以你不必担心。因此,就内存泄漏而言,局部变量通常更安全。只要清除变量(将其设置为null是清除它的常用方法),当您希望对象能够被释放时,可以在需要时使用全局变量引用。

重复变量不会导致内存泄漏。

相关问题