JS 闭包

什么是闭包

1
2
3
4
5
6
7
8
function A() {
var a = 1
B = function () { //B没有赋值的话代表作用域是全局的,才能在函数外调用B函数
console.log(a)
}
}
A()
B() // 1

闭包的定义其实很简单:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包

在 JS 中,闭包存在的意义就是让我们可以间接访问函数内部的变量

使用闭包的优缺点

避免命名空间污染

1
2
var num = 1;
(function count() { return num; })() // 1
1
2
3
4
5
var count = function () {
var num = 1;
return function () { return num; }
}
count()() // 1

虽然两段代码表达的意思一样,但是你们发现了没有第一段代码声明了一个全局变量num挂载到window中,大项目多人开发时可能会有变量名冲突的情况,容易造成命名空间污染,闭包解决了

随时可以使用但是消耗内存

我们先来看看引用计数的垃圾回收机制

跟踪记录每个值被引用的次数,当声明一个变量并将一个引用类型的值赋给该变量时,这个值的引用次数就是1,如果这个值再被赋值给另一个变量,则引用次数加1。相反,如果一个变量脱离了该值的引用,则该值引用次数减1,当次数为0时,就会等待垃圾收集器的回收

闭包创建了循环引用,就是说A对象包含一个指向B的指针,对象B也包含一个指向A的引用。 这就可能造成大量内存得不到回收(内存泄露),因为它们的引用次数永远不可能是 0

也就是说我们可以随时调用闭包,但是变量被保存起来没有被销毁,非常消耗内存

0%