闭包生成条件
- 函数嵌套
- 内部函数引用外部函数变量(函数)
function a() {
var constant = 111;
function f() {
var b = 222;
console.log(b,constant)
}
f()
}
// 在外部函数执行时就产生了闭包
a();
闭包什么时候产生?
在外部函数执行时就产生了。
为什么?不应该是内部函数执行时才产生吗?
以上代码中,在执行a函数的第一行时,也就是constant变量未赋值之前,就会在内部函数f上创建一个
closure对象这个对象就是闭包对象,此时对象值为{constant:undefined} 当执行内部函数时,此对象为{constant:111}
总结:闭包是存在于内部函数的一个对象。
闭包作用
- 在函数执行结束后,仍然可以使用其内部变量(函数),
延长局部变量的生命周期 - 外部可以在不访问对象内部变量的情况下,调用其内部方法,即开发者可以
只暴露安全的方法给用户,而不让用户访问到自己的私有变量。
function a() {
var constant = 1;
return function f() {
constant++;
console.log(constant)
}
}
let b = a();
b(); // 2
b(); // 3
观察以上代码,在函数a执行结束后,a内的所有变量和函数应该都被垃圾回收机制回收,但是闭包导致constant这个变量,还一直为我们所用。
(function() {
let name = 'jack'
let age = 11;
function alertName(){
alert(name)
}
function addAge() {
age++;
console.log(age);
}
window.addAge = addAge;
window.alertName = alertName;
})()
window.addAge()
window.addAge()
以上代码就是js最初的模块化代码,通过立即执行函数(IIFE)来包裹变量,实现变量隔离的作用。
同时,又可以通过闭包向外暴露方法,从而实现间接操作内部变量的功能。
闭包回收
闭包在什么时候会消失呢?
内部函数被回收的时候。
function a() {
var constant = 1;
return function f() {
constant++;
console.log(constant)
}
}
let b = a();
b(); // 2
b(); // 3
// 手动回收闭包
b = null
闭包应用
- 任何函数嵌套、内部函数调用外部函数变量的行为
- 创建js模块
- react中useEffect、useMemo等都在使用闭包