转载

分享几个闭包的例子

例子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  
正文到此结束
Loading...