闭包的概念
闭包就是一个函数(姑且称为父函数)内的变量被这个函数内的另一个函数(子函数)所引用,所以在父函数执行完被弹出执行栈后,子函数内仍有一块空间保存了父函数作用域内的变量,这个空间称之为闭包。依靠闭包,我们可以完成变量的私有化。不正当的使用闭包会造成内存泄漏。
几个例子
function makeAdder(x) {
return function(y) {
return x + y
}
}
var add5 = makeAdder(5)
var add10 = makeAdder(10)
console.log(add5(2)) // 7
console.log(add10(2)) // 12
add5 = null // 释放对闭包的引用
console.log(add5(1)) //Uncaught TypeError: add5 is not a function
function f1 () {
var a = 10
function f2 () {
a++
console.log(a)
}
return f2
}
var f = f1()
f() // 11
f() // 12
f() // 13
-----------------------------------------------------------
function f3 () {
var a = 10
a++
console.log(a)
}
// 每次调用这个函数都会重新在内存中创建变量,执行完之后就会销毁。
f3() // 11
f3() // 11
f3() // 11
-------------------------------------------------------------
function f1 () {
var a = 10
return function () {
a++
console.log(a)
}
}
var a1 = f1()
var a2 = f1()
// a1,a2互不干扰
a1() // 11
a1() // 12
a1() // 13
a2() //11
a2() //12
a1() //14
var add = (function () {
var counter = 0;
return function () {
return counter += 1;
}
})();
add();
add();
add(); // 3
for(var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i)
}, i * 1000)
}
for(var i = 0; i < 5; i++) {
(function(j){
setTimeout(() => {
console.log(j)
}, j * 1000)
})(i)
}
var data = []
for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i)
}
}
data[0]()
data[1]()
data[2]()
// 3 3 3
// 使用闭包
var data = []
for (var i = 0; i < 3; i++) {
data[i] = (function (j) {
return function () {
console.log(j)
}
})(i)
}
data[0]()
data[1]()
data[2]()
// 0 1 2
// 使用let
var data = []
for (let i = 0; i < 3; i++) {
data[i] = function () {
console.log(i)
}
}
data[0]()
data[1]()
data[2]()
// 0 1 2
闭包一定会造成内存泄漏吗?
不一定,如果没有引用外部函数的变量,那么外部函数的变量就会被回收,就不会造成内存泄漏。