js之闭包
如何产生闭包?
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
闭包到底是什么?
理解一:闭包就是嵌套的内部函数(绝大多数)
理解二:包含被引用变量(函数)的对象(极少数)
注意:闭包存在于嵌套的内部函数中
产生闭包的条件:
1.函数嵌套
2.内部函数引用了外部函数的数据(变量/函数)
3.调用外部函数(注意:内部函数定义执行过(函数提升))
function fn1 () {
var a = 1
var b = 'abc'
function fn2 () { // 执行函数定义
console.log(a)
}
}
fn1()
常用闭包:
1.将函数作为另一个函数的返回值
function fn1 () {
// 此时闭包就已经产生了
var a = 2
function fn2 () {
a++
console.log(a)
}
return fn2
}
fn1() // fn2
var f = fn1()
f() // 3
f() // 4
产生了一个闭包(创建了一个fn2的函数对象)
外部函数执行几次就创建了几个内部函数对象,就产生了几个闭包
2.将函数作为实参传递给另外一个函数调用
function showDelay (msg, time) {
setTimeout(function () {
alert(msg)
}, time)
}
showDelay('打死屠奕浓', 1000)
闭包的作用:
1.使用函数的内部变量在函数执行完成后,仍然存活在缓存中(延长了局部变量的生命周期)
2.让函数外部可以操作(读写)到函数内部的数据(变量/函数)
函数执行完成后,函数的内部生命的局部变量一般是不存在的,但是存在于闭包中变量是存在
闭包的生命周期:
1.产生:在嵌套内部函数定义执行完成时就产生了(不是在调用)
2.死亡:在嵌套内部函数成为垃圾对象时
function fn1 () {
var a = 1
var b = 'abc'
function fn2 () { // 执行函数定义
console.log(a)
}
}
fn1()
常用闭包:
1.将函数作为另一个函数的返回值
function fn1 () {
// 此时闭包就已经产生了(函数提升,内部函数对象已经创建)
var a = 2
function fn2 () {
a++
console.log(a)
}
return fn2
}
fn1() // fn2
var f = fn1()
f() // 3
f() // 4
f = null // 闭包死亡
闭包的应用:定义js模块
1.具有特定功能的js文件
2.将所有的数据和功能都封装在一个函数内部(私有的)
3.向外暴露对象,供外部使用方法


(function (window) {
window.msg = 'my' // 压缩时可以成为w.msg = 'my'
})(window) // 这样写的好处在代码压缩的时候能够看出来
闭包的缺点:
1.函数执行完成后,函数内的局部变量没有释放,占用内存时间变长
2.容易造成内存泄露
解决:
1.能不用闭包就不用
2.及时释放
浙公网安备 33010602011771号