Javascript闭包(Closure)

作用域

要想了解清楚闭包,首先得先了解变量作用域

因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量。局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁。在函数嵌套的情况下,内部函数的变量会逐步向外层函数寻找变量,要想访问到函数内的变量,那必须是在函数内以及函数内嵌套的函数。这样就形成了闭包。

1
2
3
4
5
6
7
8
9
10
11
12
13
function fun1() {
let num = 1;
function fun2() {
let num = 2;
function fun3() {
console.log(num);
}
fun3();
}
fun2();
}

fun1()

闭包

官方的解释是:

闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

通俗的解释:

闭包就是能够读取其他函数内部变量的函数。

1
2
3
4
5
6
7
8
9
10
11
12
function box() {
let box_num = 1;
function boxNumAdd() {
box_num++
return box_num;
}
return boxNumAdd
}

const boxNumAdd = box()

console.log(boxNumAdd())

作用

  1. 给函数添加一些属性
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function Circle(r) {
    this.r = r;
    }
    Circle.PI = 3.14159;
    Circle.prototype.area = function () {
    return Circle.PI * this.r * this.r;
    }
    let c = new Circle(1.0);
    alert(c.area()); //3.14159
  2. 封装特定功能集合
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    App({
    onLaunch(options) {
    this.globalData.corpId = options.query.corpId;
    },
    onShow() {
    console.log('App Show');
    },
    onHide() {
    console.log('App Hide');
    },
    globalData: {
    corpId:''
    }
    });
  3. 保护函数内的变量安全

以闭包的例子为例,函数box中box_num只有函数boxNumAdd才能访问,而无法通过其他途径访问到,因此保护了i的安全性。

特性

  1. 闭包外层函数变量被内层函数引用的情况下,就算外层函数执行结束了,函数变量还是可以被访问;
  2. 闭包中必须包含指向外部函数的引用,内部函数不一定需要 return 给外部调用;

风险

  • 闭包在IE浏览器上可能导致内存泄漏风险(该问题不是闭包的问题,是IE浏览器本身bug问题),
Author: suce
Link: https://haoubox.cn/2021/04/01/Javascript闭包-Closure/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.