浅释Javascript的闭包

以下为个人理解。

“闭包(closure)”,是函数和数据的封装,相当于“对象”。只是在javascript里,形式上和c++有很大的不同。

在js中,当出现函数嵌套时,我把外层的称为母函数,内层的称为子函数。

1、母函数function即相当于class。
2、母函数内的子函数,用return返回,即相当于成员函数。
3、没有用return返回的,即相当于私有函数。
4、数据为私有变量。

当母函数被执行后,它的整体,包括子函数、初始化参数就保留在了内存中,即相当于创建了一个对象。这就是所谓的“闭包”。

1、只返回一个匿名成员函数的情况,闭包即函数
function myFunc(初始参数) {
    
    return function(动态参数){
        ...
    }
  
    function privatefunc(...){
    }
 

}

实例化:
var myClosure1= myFunc(初始化参数1);
var myClosure2= myFunc(初始化参数2);

调用时无需写成员函数名:

myClosure1(动态参数1);
myClosure2(动态参数2);




2、成员函数有名称的情况,成员函数可以返回一个或多个,调用时和使用对象一样了:
var makeCounter = function() {
  var privateCounter = 0;


  function changeBy(val) { //私有函数
    privateCounter += val;
  }

  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }
};

var Counter1 = makeCounter();
var Counter2 = makeCounter();

console.log(Counter1.value()); /*  0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /*  2 */

Counter1.decrement();
console.log(Counter1.value()); /*  1 */

console.log(Counter2.value()); /*  0 */

同样可使用初始化参数和动态参数。
3、如果只需要一个实例,可以用“立即执行函数”来定义和初始化
var myClosure = function(初始参数名) {
    return function(动态参数名){
        ...
    }
}(初始参数值);

调用:
myClosure(动态参数);


4、在循环体中初始化回调函数时,每个循环要传入不同值的初始化参数,可使用闭包。


回调函数相当于子函数。如果不使用闭包
for(var x=0;x<max;x++)
{
onmousedown=function(e){console.log(x);}
}
当它被触发时,它去读取母体中x的值,这时候x=max。

所以,
for(var x=0;x<max;x++)
{
onmousedown=function(x){return function(e){console.log(x);}}(x);
}
每次循环都产生一个闭包,保存了不同的x。


也可以使用let或foreach达到同样的效果。


参考文章: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

你可能想看:
标签: 初始化
分享给朋友: