js闭包

 

function foo() {
            var x = 10;
            return function bar() {
                console.log(x);
            }
        }
        var returntedFunction = foo();
        var x = 20;
        returntedFunction();

1、输出10而不是20,这种形式的作用域称为静态作用域[static/lexical scope]。上面的x变量就是在函数bar的[[Scope]]中搜寻到的。理论上来说,也会有动态作用域[dynamic scope], 也就是上述的x被解释为20,而不是10. 但是EMCAScript不使用动态作用域。

 

var x = 10;
        function foo() {
            console.log(x);
        }
        (function (funArg) {
            var x = 20;
            funArg();
        })(foo);

2、输出10而不是20

闭包是一系列代码块(在ECMAScript中是函数),并且静态保存所有父级的作用域。通过这些保存的作用域来搜寻到函数中的自由变量。



function baz() {
            var x = 1;
            return {
                foo: function foo() { return (x+=3); },
                bar: function bar() { return (x+=3); }
            };
        }

        var closures = baz();

        console.log(
          closures.foo(), // 4
          closures.bar()  // 7
        );

3、几个函数可能含有相同的父级作用域,例如好几个内部或者全局的函数,这样Scope中存在的变量是会共享的。一个闭包中变量的变化,也会影响另个闭包。

 

var data = [];
        for (var k = 0; k < 3; k++) {
            data[k] = function () {
                console.log(k);
            };
        }
        data[0]();//3
        data[1]();//3
        data[2]();//3

4、在某个循环中创建几个函数时,如果在创建的函数中使用循环变量(如k),那么所有的函数都使用同样的循环变量,导致得不到预期值,因为所有函数共享同一个scope,其中循环变量为最后一次赋值

 

var data = [];
        for (var k = 0; k < 3; k++) {
            data[k] = (function (x) {
                return function () {
                    console.log(x);
                };
            })(k);
        }
        data[0]();//3
        data[1]();//3
        data[2]();//3

5、其中一种技巧是在作用域链中提供一个额外的对象,比如增加一个函数

 

posted @ 2016-11-11 18:09  wjl910  阅读(137)  评论(0)    收藏  举报