相关疑难解决方法(0)

JavaScript闭包与匿名函数

我的一个朋友和我正在讨论什么是JS的封闭,什么不是.我们只是想确保我们真正理解它.

我们来看看这个例子吧.我们有一个计数循环,并希望在控制台上打印计数器变量延迟.因此,我们使用setTimeout闭包来捕获计数器变量的值,以确保它不会打印值N的N倍.

错误的解决方案,无需关闭或接近任何倒闭将是:

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
Run Code Online (Sandbox Code Playgroud)

这当然会打印10次i循环后的值,即10.

所以他的尝试是:

for(var i = 0; i < 10; i++) {
    (function(){
        var i2 = i;
        setTimeout(function(){
            console.log(i2);
        }, 1000)
    })();
}
Run Code Online (Sandbox Code Playgroud)

按预期打印0到9.

我告诉他,他并没有使用封闭捕获i,但他坚持认为他是.我证明他没有使用闭包,将for循环体放在另一个setTimeout(将他的匿名函数传递给setTimeout),再次打印10次10​​.如果我将他的函数存储在a中var并在循环之后执行它同样适用,也打印10次10​​.所以我的论点是他并没有真正捕获它的值i,使他的版本不是一个闭包.

我的尝试是:

for(var i = 0; i < …
Run Code Online (Sandbox Code Playgroud)

javascript closures scope

551
推荐指数
10
解决办法
11万
查看次数

关于闭包,LexicalEnvironment和GC

作为ECMAScriptv5,每当控件输入代码时,enginge创建一个LexicalEnvironment(LE)和一个VariableEnvironment(VE),对于功能代码,这两个对象是完全相同的引用,它是调用NewDeclarativeEnvironment(ECMAScript v5 10.4)的结果. 3),在函数代码中声明的所有变量都存储在VariableEnvironment(ECMAScript v5 10.5)的环境记录组件中,这是闭包的基本概念.

令我困惑的是Garbage Collect如何使用这种闭包方法,假设我有以下代码:

function f1() {
    var o = LargeObject.fromSize('10MB');
    return function() {
        // here never uses o
        return 'Hello world';
    }
}
var f2 = f1();
Run Code Online (Sandbox Code Playgroud)

在该行之后var f2 = f1(),我们的对象图将是:

global -> f2 -> f2's VariableEnvironment -> f1's VariableEnvironment -> o
Run Code Online (Sandbox Code Playgroud)

从我的小知识来看,如果javascript引擎使用引用计数方法进行垃圾收集,则该对象o至少有1次重新引用,并且永远不会被GCed.显然这会导致浪费内存,因为o永远不会被使用但总是存储在内存中.

有人可能会说引擎知道f2的VariableEnvironment …

javascript closures garbage-collection

13
推荐指数
1
解决办法
691
查看次数

JavaScript中的每个函数都是闭包是真的吗?

我知道JavaScript中的每个函数都是一个第一类对象,它有一个内部属性[[scope]],它承载函数自由变量的绑定记录.但是,有两种特殊情况.

  1. Function构造函数创建的函数也是一个闭包吗?Function构造函数创建的函数对象是特殊的,因为它的[[scope]]可能不引用其外部函数的词法环境,而只引用全局上下文.例如,

    var a = 1; 
    var fn = (function outer() {
        var a = 2; 
        var inner = new Function('alert(a); ');
        return inner;
    })();
    fn(); // will alert 1, not 2.
    
    Run Code Online (Sandbox Code Playgroud)

    这是不直观的.这也叫封闭吗?

  2. 如果内部函数没有任何自由变量,我们可以说在创建内部函数时会形成闭包吗?例如,

    // This is a useless case only for academic study
    var fn = (function outer() {
        var localVar1 = 1,
            localVar2 = 2;
        return function() {};
    })();
    
    Run Code Online (Sandbox Code Playgroud)

    在这种情况下,fn指的是作为内部函数创建的空函数对象.它没有自由变量.在这种情况下我们可以说闭合形成了吗?

javascript closures ecmascript-5

8
推荐指数
2
解决办法
1224
查看次数