分享几个闭包的例子

例子1

  • 马上挪用表达式会马上实行,不须要test()挪用
  • 显现挪用test()只是会挪用一个匿名函数
  • 局部变量i不会跟着挪用的完毕而被接纳,而是一向保留在内存中
javascriptvar test = (function () {
    console.log("test func");
    var i = 0;
    return function () {
        console.log(i);
        return i++;
    }
})();

console.log("........");
test();     //0
test();     //1
test();     //2

// output
// test func
// ........
// 0
// 1
// 2

例子2

  • test不是马上挪用的,须要显现挪用test()返回匿名函数的援用,如:var a = test(),这时候a指向匿名函数
  • a()挪用这个匿名函数,局部变量i关于a来讲一向会常驻内存中
  • var b = test(),再次挪用test,b会返回一个新的匿名函数的拷贝,而且i关于b也是唯一的
javascriptvar test = function () {
    console.log("test func");
    var i = 0;
    return function () {
        console.log(i);
        return i++;
    }
};

console.log("........");
var a = test();
a();    //0
a();    //1
a();    //2

var b = test()
b();    //0

// output
// ........
// test func
// 0
// 1
// 2
// test func
// 0

例子3

  • 不运用闭包,轮回完毕后i=3
javascriptvar arr = [1, 2, 3];
var obj = {};

var test = function () {
    for (var i=0; i<arr.length; i++) {
        obj[i] = function () {
            console.log(i);
        };
    }
}

test();

var fn0 = obj[0];
var fn1 = obj[1];
var fn2 = obj[2];

fn0();   //3
fn1();   //3
fn2();   //3
  • 在for轮回里创建了一个马上挪用函数表达式
  • fn0,fn1,fn2离别指向了匿名函数的援用
  • fn0(),fn1(),fn2()都接见了i(这个i是位于这个匿名函数的上层作用域链,它会被保留在内存中,关于每个函数援用来讲i是唯一的)
javascriptvar arr = [1, 2, 3];
var obj = {};

var test = function () {
    for (var i=0; i<arr.length; i++) {
        (function (i) {
            obj[i] = function () {
                console.log(i);
            };
        })(i);  //i作为参数传给马上挪用函数
    }
};

test();

var fn0 = obj[0];
var fn1 = obj[1];
var fn2 = obj[2];

fn0();   //0
fn1();   //1
fn2();   //2
  • 下面这个例子为了加深明白
javascriptvar arr = [1, 2, 3];
var obj = {};

var test = function () {
    for (var i=0; i<arr.length; i++) {
        (function (i) {
            obj[i] = function () {
                console.log(i++);
            };
        })(i);  //i作为参数传给马上挪用函数
    }
};

test();

var fn0 = obj[0];
var fn1 = obj[1];
var fn2 = obj[2];

// 两次fn0()接见同一个内存中的i值
fn0();  //0
fn0();  //1

// 两次fn1()接见同一个内存中的i值
fn1();  //1
fn1();  //2

// 两次fn2()接见同一个内存中的i值
fn2();  //2
fn2();  //3

例子4

javascriptvar arr = [1, 2, 3];

// 用来寄存函数的数组
var fns = [];

var add = function () {
    for (var i = 0; i < arr.length; i++) {
        (function (i) {
            // 把匿名函数push到fns中
            fns.push(function () {
                // 因为函数援用了上层作用域链的i,当被挪用时i值不会被转变
                console.log(arr[i]);
            });
        })(i);
    }
};

// 遍历fns实行数组中的函数
var start = function () {
    for (var i = 0; i < fns.length; i++) {
        // 实行fns中的匿名函数
        fns[i]();
    }
};

add();
start();

// output
// 1
// 2
// 3
    原文作者:ttian226
    原文地址: https://segmentfault.com/a/1190000002957434
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞