简单来说,就是呼叫函式内的函式,将记忆体封存在内层。
像这样,我们把 count 封装在 counter() 当中,不但可以让里面的 count 不会暴露在 global 环境造成变数冲突,也可以确保内部 count 被修改。
function counter(){ var count = 0; function innerCounter(){ return ++count; } return innerCounter;}var countFunc = counter();console.log( countFunc() ); // 1console.log( countFunc() ); // 2console.log( countFunc() ); // 3
外值得一提的是,过去我们需要新增另一个计数器时,可能会再新增另一个全域变数去储存另一个 count 的状态。 而改用闭包的写法之后,只需要像这样:此时你就会发现 countFunc 与 countFunc2 分别是「独立」的计数器实体,彼此不会互相干扰!function counter(){ var count = 0; return function(){ return ++count; }}var countFunc = counter();var countFunc2 = counter();console.log( countFunc() ); // 1console.log( countFunc() ); // 2console.log( countFunc() ); // 3console.log( countFunc2() ); // 1console.log( countFunc2() ); // 2
Closure常见应用
function callMethod(newMoney) { var money = newMoney || 1000; return function (price) { money = money - price; return money; }}let updateMyMoney = callMethod(10000000000);let updateYourMoney = callMethod(1000);console.log(updateMyMoney(100));console.log(updateYourMoney(100));
实现 private=>使用闭包来定义公共函数,且其可以访问私有函数和变数,这个方式也称为模组模式(module pattern)。
/*自调用函数,共用生存域*/function Counter() { let innerCounter = 0; function change(val) { innerCounter += val; } return { addone: function() { change(1); }, deone: function() { change(-1); }, value: function() { return innerCounter; } }}let newCounter = Counter()console.log(newCounter.value()); /* logs 0 */newCounter.addone();newCounter.addone();console.log(newCounter.value()); /* logs 2 */newCounter.deone();console.log(newCounter.value()); /* logs 1 */