闭包是否记住引用或变量

时间:2015-08-14 04:30:34

标签: javascript

我早就读过,在JS中,一个闭包会记住一个变量指向的引用。如果是这样,以下是如何工作的?

var v = {a: 5};

function f1() {
   console.log(v); // outputs {a: 5}
    v = {b: 3};
}

function f2() {
    console.log(v); // outputs {b: 3}
}

setTimeout(f1, 1000);
setTimeout(f2, 2000);

我已更改v变量的引用,但f2函数显示此新引用的值,而不是显示旧引用的值。怎么样?

修改

(function () {
    var v = {a: 5};

    function f1() {
        console.log(v); // outputs {a: 5}
        v = {b: 3};
    }

    function f2() {
        console.log(v); // outputs {b: 3}
    }

    f1();
    f2();
})();

EDIT2:

var f = (function () {
    var v = {a: 5};

    function f1() {
        console.log(v); // outputs {a: 5}
        v = {b: 3};
    }

    function f2() {
        console.log(v); // outputs {b: 3}
    }

    setTimeout(f1, 1000);

    return f2;
})();

setTimeout(function() {
    f();
}, 3000);

4 个答案:

答案 0 :(得分:3)

您只需修改和访问函数中的单个全局变量。这里没有持久的关闭。

每个console.log(v)只输出该全局变量的当前值。

您对vf1()的分配只会更改全局v的值。

setTimeout()操作只会使这里的故事复杂化。您将获得相同的结果:

f1();
f2();

以下是对正在发生的事情的注释:

// declare global variable v and initialize it
var v = {a: 5};

function f1() {
   // output current value of v
   console.log(v); // outputs {a: 5}
   // set v to a new value
   v = {b: 3};
}

function f2() {
    // output current value of v
    console.log(v); // outputs {b: 3}
}

因此,如果您打开函数调用,则会有以下代码序列:

var v = {a: 5};
console.log(v); // outputs {a: 5}
v = {b: 3};
console.log(v); // outputs {b: 3}

在第二个示例中,您刚刚将变量v移动到公共和共享父作用域中。效果仍然相同,因为两个函数都访问相同的变量v。你在第二个例子中所拥有的是来自外部函数(不是闭包)的“范围”。只要外部函数处于活动状态,该范围就会存在,因此f1()f2()共享该范围,因为它们在该范围内。函数可以访问自己范围内或父函数范围内或全局范围内的任何内容。

请记住,变量可以直接包含原始值,如6null,但它指向对象引用(因为对象的赋值是通过指针)。因此,当您访问变量v时,它会获得指向v当前包含的对象的指针并输出该对象。当您稍后将新对象分配给v时,它只是将另一个对象指针放入v,当您再次访问v时,它会获得指向v的指针到那个新对象并输出该对象。变量v在所有情况下都相同,但v的内容会发生变化。

如果你知道像C / C ++这样的语言,那么在Javascript中将对象分配给变量就像在变量的内存槽中放置一个指向该对象的指针。与C / C ++不同,Javascript中的指针是透明的(你不必知道它们使用它们),但这基本上就是它们的工作原理(它比那复杂一点,因为还有引用计数和运行时类型信息,但我只想给你一般的想法。

答案 1 :(得分:0)

使用

在阻止范围内创建变量时
v = {b: 3};

就像你在

中所做的那样
function f1() {
   console.log(v); // outputs {a: 5}
    v = {b: 3};
}

它将始终更改对它的全局引用

function f1() {
       console.log(v); // outputs {a: 5}
       var v = {b: 3}; // this creates a variable in this scope
    }

答案 2 :(得分:0)

这种情况正在发生,因为您的变量 v 处于全局范围内。因此,它将在函数 f1 f2 中可用,并且任何更改这将在两个功能中都可用。

以下是示例:http://www.dotnet-tricks.com/Tutorial/javascript/aKEQ220913-Understanding-Local-and-Global-Variables-in-JavaScript.html

答案 3 :(得分:0)

首先 V 是全局对象,因此无论何时通过引用对象v更改值,您是否从 f1或f2函数 进行更改价值将全球变化 ...... !!