前言
闭包经常在面试中被问到,但是有的同学总是回答的不好,阅读本文让你的回答得满分。
闭包
闭包可以理解为可以访问另一个函数的作用域的变量的函数。
在本质上闭包是连接外部函数和内部函数的桥梁。
闭包的示例
示例一
var Counter = (function () {
var privateCounter = 0
return {
increment: function () {
privateCounter += 1
},
decrement: function () {
privateCounter += -1
},
value: function () {
return privateCounter
}
}
})()
console.log(Counter.value()) // 0
Counter.increment()
Counter.increment()
console.log(Counter.value()) // 2
Counter.decrement()
console.log(Counter.value()) // 1
示例一中的闭包有Counter.value、Counter.increment、Counter.decrement。
示例二
let liDomList = document.querySelectorAll('li')
for (var i = 0; i < liDomList.length; i++) {
(function (i) {
liDomList[i].onclick = function () {
console.log(i)
}
})(i)
}
示例二中的闭包有liDomList[i].onclick
闭包的作用
示例二中,内部函数a(liDomList[i].onclick),外部函数b((function (i) {})
外部函数b执行完后,闭包使得Javascript的垃圾回收机制不会收回a所占用的资源, 因为b的执行需要依赖a中的变量i。
延长变量生命周期
示例二中i的生命周期延长了,使得执行a的时候,依然可以获取到变量i。
模拟私有变量
示例一中,privateCounter变量就是一个私有变量,在其他函数中不能直接使用。
闭包的使用
闭包实现只读,只写,可读可写
var property = (function (opts) {
var property = '闭包'
var hasSet = opts.hasSet || false
var hasGet = opts.hasGet || false
var res = {}
if (hasGet) {
res.get = function () {
return property
}
}
if (hasSet) {
res.set = function (v) {
property = v
}
}
return res
})({hasSet: true, hasGet: true})
console.log(property.get())
property.set('闭包DEMO')
console.log(property.get())
谢谢阅读!