1.如何产生闭包
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
function fn1(){
// 此时闭包就已经产生了(函数提升,内部函数对象已经)
var a = 2
function fn2(){
// 执行函数定义就会产生闭包(不用调用内部函数)
console.log(a)
}
}
2.闭包是什么?
理解一:闭包是嵌套的内部函数
理解二:包含被引用变量(函数)的对象
注:闭包存在于嵌套的内部函数中
3.产生闭包的条件?
- 函数嵌套
- 内部函数引用了外部函数的数据(变量、函数)
4.常见的闭包
4.1 将内部函数作为外部函数的一个返回值返回
外部函数被调用几次,就产生了几次闭包,这里只产生了一次闭包
function fn1 () {
var a = 2
function fn2 () {
a++
console.log(a)
}
return fn2
}
// fn1的地址值传给了f,fn1销毁了,f还存在
var f = fn1() // 产生闭包,返回的是内部函数
f() // 3 调用的是fn2
f() // 4
4.2 将函数作为实参传递给另一个函数使用
function showDelay (msg, time) {
setTimeout(function () {
alert(msg)
}, time)
}
showDelay('hello', 2000)
5.闭包的作用
- 使用函数的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
- 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
6.问题
1.函数执行完后,函数内部声明的局部变量是否还存在?
一般是不存在的,存在于闭包中的变量才有可能存在
2.在函数外部能直接访问函数内部的局部变量吗?
不能,但我们可以通过闭包让外部操作它
7.闭包的生命周期
产生: 在嵌套内部函数定义执行完成时就产生了(不是在调用)
死亡:在嵌套的内部函数成为垃圾对象时
function fn1 () {
// 此时闭包已经产生了(函数提升,内部函数对象已经创建了)
var a = 2
function fn2 () {
a++
console.log(a)
}
return fn2
}
var f = fn1()
f() // 3
f() // 4
f = null // 闭包死亡(包含闭包的函数对象成为垃圾对象)