为什么在重新定义函数时函数变量会继续存在?

时间:2010-12-17 14:36:50

标签: javascript function

作为this question仍然试图解决Javascript函数异常的后续行为,有人可以解释为什么以下代码有效吗?

我的文字(Javascript模式)声明:

  

如果你创建一个新的功能和   将它分配给相同的变量   你已经掌握了另一个功能   用。覆盖旧函数   新的。

这将使我假设在以下代码中,当创建函数count的第二个定义时,变量nametest将被破坏。

变量countname在哪里?

$(document).ready(function() {

    var test = function() {
        var name = 'The Test Function';
        var count = 1;
        console.log(name + ' has been setup');
        test = function() {
            console.log('Number of times ' + name + ' has been called: ' + count);
            count++;
        };
    }
    test();
    test();
    test();
    test();
    test();
});

输出:

alt text

3 个答案:

答案 0 :(得分:7)

替换test函数,但是你要用一个“关闭”(有一个持久引用)第一个函数调用创建的变量的函数替换它。这就是为什么你看到它们继续存在,即使之前的函数调用已经返回。 More about closures here,它们是语言中非常重要的一部分。

以下是对正在发生的事情的细分。

  1. 您创建了一个功能并将其分配给test
  2. 您致电test
  3. JavaScript解释器为test的调用设置了一个名为执行上下文的对象。 执行上下文具有称为变量对象的内容。此对象(您无法直接访问)具有所有参数的属性,并且var的调用具有test
  4. test中的代码设置了一些内容,包括创建 new 函数并将其分配给test变量。新函数对创建它的执行上下文有持久的引用,这意味着即使第一次调用test返回,新函数仍然可以访问(通过变量对象)创建的变量电话。
  5. 您再次致电test(新的)。
  6. 它访问第一次调用创建的变量(变量对象的属性)。

答案 1 :(得分:0)

通过在第一个函数中定义第二个test函数(声明变量namecount),您将创建一个闭包,保持对这些变量的引用即使对旧test函数的引用已经消失。

如果您从第一个test功能中取出第二个undefined功能,namecount将获得{{1}}。

答案 2 :(得分:0)

该功能尚未重新定义。已经为先前保存对旧函数的引用的变量分配了对新函数的引用。

由于新函数引用了旧函数中定义的变量,因此垃圾回收不会删除它们。