JavaScript闭包应用介绍
一、闭包的概念和特性
function makeFab () {
let last = 1, current = 1
return function inner() {
[current, last] = [current + last, current]
return last
}
}
let fab = makeFab()
console.log(fab()) // 1
console.log(fab()) // 2
console.log(fab()) // 3
console.log(fab()) // 5
二、闭包——函数式编程之魂
在JavaScript里,我们可以像操作普通变量一样,把函数在我们的代码里抛来抛去,然后在某个时刻调用一下,这就是所谓的函数式编程。
function confirm (confirmText, confirmCallback, cancelCallback) {
// 插入提示框DOM,包含提示语句、确认按钮、取消按钮
// 添加确认按钮点击事件,事件函数中做dom清理工作并调用confirmCallback
// 添加取消按钮点击事件,事件函数中做dom清理工作并调用cancelCallback
}
function removeItem (id) {
confirm('确认删除吗?', () => {
// 用户点击确认, 发送远程ajax请求
api.removeItem(id).then(xxx)
}, () => {
// 用户点击取消,
console.log('取消删除')
})
}
三、闭包的一些例子
1. 防抖、节流函数
function debounce (func, time) {
let timer = 0
return function (...args) {
timer && clearTimeout(timer)
timer = setTimeout(() => {
timer = 0
func.apply(this, args)
}, time)
}
}
input.onkeypress = debounce(function () {
console.log(input.value) // 事件处理逻辑
}, 500)
function throttle(func, time) {
let timer = 0 // 定时器标记相当于一个锁标志
return function (...args) {
if (timer) return
func.apply(this, args)
timer = setTimeout(() => timer = 0, time)
}
}
2. 优雅解决按钮多次连续点击问题
let clickButton = (function () {
let lock = false
return function (postParams) {
if (lock) return
lock = true
// 使用axios发送请求
axios.post('urlxxx', postParams).then(
// 表单提交成功
).catch(error => {
// 表单提交出错
console.log(error)
}).finally(() => {
// 不管成功失败 都解锁
lock = false
})
}
})()
button.addEventListener('click', clickButton)
function singleClick(func, manuDone = false) {
let lock = false
return function (...args) {
if (lock) return
lock = true
let done = () => lock = false
if (manuDone) return func.call(this, ...args, done)
let promise = func.call(this, ...args)
promise ? promise.finally(done) : done()
return promise
}
}
let clickButton = singleClick(function (postParams) {
if (!checkForm()) return
return axios.post('urlxxx', postParams).then(
// 表单提交成功
).catch(error => {
// 表单提交出错
console.log(error)
})
})
button.addEventListener('click', clickButton)
let print = singleClick(function (i, done) {
console.log('print is called', i)
setTimeout(done, 2000)
}, true)
function test () {
for (let i = 0; i < 10; i++) {
setTimeout(() => {
print(i)
}, i * 1000)
}
}
3. 闭包模拟私有方法或者变量
function makePlayer () {
let exp = 0 // 经验值
return {
getExp () {
return exp
},
changeExp (delta, sReason = '') {
// log(xxx),记录变动日志
exp += delta
}
}
}
let p = makePlayer()
console.log(p.getExp()) // 0
p.changeExp(2000)
console.log(p.getExp()) // 2000
四、总结
评论