闭包

@Closure
含义
函数的嵌套
在一个函数内部定义另外一个函数,并返回该内部函数;该内部函数形成闭包,可以访问外部的函数和变量
作用
保护变量

. 利用创建私有变量来保护数据、隐藏数据;外部无法直接访问,只能通过内部函数访问

. 尽量少使用全局变量;避免全局变量污染环境

. 通常使用return把内部变量/临时变量,如instance,暴露出去给外部使用

数据封装
记忆效果
函数工厂
异步操作
const singleton = (function () {
  let instance;
  
  return function () {
    if (!instance)
      //创建instance
    return instance
  }
})()
应用
给变量赋值/返回值
. 执行其它函数/闭包函数获取返回值
let a;
function fa() {
    let tmp = 10;
    return function res() {
        return tmp;
    }
}
a = fa();
console.log(a());
. 还可以携带参数
function fb() {
    let a = 10;
    return function res(inc) {
        a += inc;
        return a;
    }
}
let b = fb();
console.log(b(2));
console.log(b(2));
给函数赋值
. 执行一个其它函数/闭包函数来给某个函数赋值;和上述略有不同
let fn;
function assign() {
    let tmp = 12;
    fn = function () {
        return tmp;
    }
}
assign();
console.log(fn());
案例 Cases
[] 统计函数调用次数
传统方法:使用全局变量
let num = 0;
function fn() {
    num++;
    console.log('fn() done ', num);
    return num;
}
. 按F12在控制台调试;因为使用全局变量,当该变量被手动修改后,结果就会错误
fn()
fn() done  1
1
fn()
fn() done  2
2
fn()
fn() done  3
3
fn()
fn() done  4
4
num=100
100
fn()
fn() done  101
101
. 使用闭包:以函数的形式返回执行结果
function fn() {
    let num = 0;
    return function () {
        num++;
        console.log('fn() done ', num);
    }
}
let a = fn();
. 按F12调试,结果正常
a()
fn() done  1
undefined
a()
fn() done  2
undefined
num=100
100
a()
fn() done  3
undefined
a()
fn() done  4
undefined