JavaScript中的闭包

闭包:

在MDN中的解释:闭包是指那些能够访问独立(自由)变量的函数 (变量在本地使用,但定义在一个封闭的作用域中)。换句话说,这些函数可以“记忆”它被创建时候的环境。

简单理解就是:

如果一个函数会在其父级函数返回之后留住对父级作用域的链接的话,相关闭包就会被创建出来。

闭包#1:

var a = "global variable";

var F = function(){

       var b = "local variable";

       var N = function(){

              var c = "inner local";

              return b;

       }

       return N;

}

//函数N有自己的私有空间,同时可以访问F()的空间和全局空间,所以b对它来说是可见的,因为F()是一个全局函数,所以可以将它的返回值赋值给

//其他全局变量,生成一个可以访问F()私有空间的新全局函数。

var inner = F();

inner();

 

 

闭包#2:

F()不再返回新函数,而是直接在函数体内创建一个新的全局函数inner()。

var inner;

var F = function(){

       var b = "local variable";

       var N = function(){

              return b;

       };

       inner = N;

}

//此时,调用F()函数,则会创建一个新的函数N,并且将它赋值给全局变量inner。

F();

inner();

 

 

闭包#3:

该函数返回一个子函数,这个子函数返回的则是复函数的参数:

function F(param){

       var N = function(){

              return param;

       }

       param++;

       return N;

}

var inner = F(10);

inner();//11

 

于是我们知道,函数所绑定的是作用域本身,而不是在函数定义时,该作用域中的变量返回的值。

 

循环中的闭包:

来看一个三次的循环操作,在每次迭代中都会创建一个返回当前序列号的新函数,该函数会被添加到一个数组中并返回。

function F(){

       var arr = [],i;

       for(i=0;i<3;i++){

              arr[i]=(function(x){

                     return function(){

                            return x;

                     }

              }(i));

       }

       return arr;

}

var arr = F();

arr[0]();

//或者,不使用即时函数,将i的值本地化:

function F(){

       function binder(x){

              return function(){

                     return x;

              }

       }

       var arr = [],i;

       for(i=0;i<3;i++){

              arr[i] = binder(i);

       }

       return arr;

}

 

 

关于闭包的应用:

应用#1:

将私有变量保护起来:

var getValue,setValue;

(function(){

       var secret = 0;

       getValue = function(){

              return secret;

       };

       setValue = function(v){

              if(typeof v === 'number'){

                     secret = v;

              }

       }

}());

getValue();

setValue(11);

getValue();//11

 

 

应用#2:(迭代器)

将下一个封装给易于使用的next()函数。

function setup(x){

       var i = 0;

       return function(){

              return x[i++];

       }

}

var next = setup(['a','b','c']);

next();

"a"

next()

"b"

next()

"c"

 

 

 

应用#3:

function makeSizer(size) {

       return function() {

              document.body.style.fontSize = size + 'px';

      };

}

 

var size12 = makeSizer(12);

var size14 = makeSizer(14);

var size16 = makeSizer(16);

document.getElementById('size-12').onclick = size12;

document.getElementById('size-14').onclick = size14;

document.getElementById('size-16').onclick = size16;

 

 

应用#4:

(模块模式,用闭包来定义公共函数,且其可以访问私有函数)

var Counter = (function(){

       var privateCounter = 0;

       function changeBy(val){

              privateCounter += val;

       }

       return {

              increment:function(){

                     changeBy(1);

              },

              decrement:function(){

                     changeBy(-1);

              },

              value:function(){

                     return privateCounter;

              }

       }

})();

console.log(Counter.value());

Counter.increment();

Counter.increment();

console.log(Counter.value());

Counter.decrement();

console.log(Counter.value());

 

 

转载于:https://www.cnblogs.com/jsbally/p/6418026.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值