美文网首页
Scope & Closures

Scope & Closures

作者: lesliefang | 来源:发表于2017-03-01 15:41 被阅读0次
    JS 也是编译型语言,并不是边解释边执行的。
    编译的时机是代码即将执行之前。
    Hoisting

    编译时 JS 会把函数和变量的声明提升到它们所在的 scope 的顶层

    a = 2;
    var a;
    console.log( a ); // 2
    

    等价于下面的代码

    var a;
    a = 2;
    console.log( a );
    
    console.log( a ); // undefined
    var a = 2;
    

    等价于下面的代码

    var a;
    console.log( a );
    a = 2;
    
    foo();
    
    function foo() {
        console.log( a ); // undefined
        var a = 2;
    }
    

    同理 foo 和 a 的声明都被提升, 还是打印 undefined

    Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.
    有点只可意会不可言传的感觉
    闭包就是当一个函数在它的词法域之外执行的时候,仍然可以访问它所在的词法域(的变量和函数)
    function foo() {
        var a = 2;
    
        function bar() {
            console.log( a );
        }
    
        return bar;
    }
    
    var baz = foo();
    
    baz();
    

    foo 返回了 bar 函数, foo 执行完毕后,baz 引用了返回的函数,这时再执行 baz 仍然可以访问到变量 a。 这里 baz 是在 global 域执行的而不是在 foo 域执行的。

    
    for (var i=1; i<=5; i++) {
        setTimeout( function timer(){
            console.log( i );
        }, i*1000 );
    }
    

    将打印 5 个 6,i 会被提升到 global 域,每个 setTimeout 包围的都是 global 域中的 i

    解决方案就是让每个 setTimeout 都包围自己的域中的变量

    for (var i=1; i<=5; i++) {
        (function(){
            var j = i;
            setTimeout( function timer(){
                console.log( j );
            }, j*1000 );
        })();
    }
    

    每个 setTimeout 都包围在 function 形成的独立的域中,每个域中都有自己的变量 j。

    相关文章

      网友评论

          本文标题:Scope & Closures

          本文链接:https://www.haomeiwen.com/subject/yszqgttx.html