JavaScript的闭包
面试的时候被问到“平常用闭包都做过哪些事情?”
闭包的概念
《你不知道的JavaScript(上卷)》
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行
关于闭包的概念,仅此一句就够了。
解读闭包
正常情况下,当词法作用域内的代码执行完毕后,在这个词法作用域内定义的变量都会被回收掉。
不正常的情况下,也就是有闭包的时候。这个词法作用域内定义的变量“可以被记住”,而不会被回收掉。记住这些变量的是一个函数。
function P(){
let a = "a"
let b = "b"
return function innerFunc(){
return a+b
}
}
// 在作用域外部访问到了P作用域内部定义的ab变量
// ab
P()()
在上面的例子中,innerFunc “记住了”所在的词法作用域(a和b变量),产生了闭包。
innerFunc 函数在 P 的作用域外部执行时,也能访问到内部的词法作用域。
使用闭包的例子
1.模拟定义一个对象的私有属性
const P = (function (){
let _gender = ""
function People(name,gender){
this.name = name
_gender = gender
}
People.prototype.getGender = function (){
return _gender
}
return People
})()
const people = new P("小明","male")
// { name: '小明' }
console.log(people)
// male
console.log(people.getGender())
2.给标签添加事件
有作用域的地方就有闭包
const container = [{},{},{}]
for (let i = 0;i<container.length;i++){
container[i].run = function () {
console.log("当前是第"+ ++i +"个容器")
}
}
// 当前是第1个容器
container[0].run()
// 当前是第3个容器
container[2].run()
用 let 声明 i 变量,循环体运行了3次,一共就创建了3个块级作用域。然后通过三个匿名函数“记住了”这3个块级作用域(i变量 ),创建了3个闭包。