【JS】741- JavaScript 闭包应用介绍

一、闭包的概念和特性
function makeFab () {let last = 1, current = 1return function inner() {[current, last] = [current + last, current]return last}}let fab = makeFab()console.log(fab()) // 1console.log(fab()) // 2console.log(fab()) // 3console.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 = 0return function (...args) {timer && clearTimeout(timer)timer = setTimeout(() => {timer = 0func.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) returnfunc.apply(this, args)timer = setTimeout(() => timer = 0, time)}}
2. 优雅解决按钮多次连续点击问题
let clickButton = (function () {let lock = falsereturn function (postParams) {if (lock) returnlock = 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 = falsereturn function (...args) {if (lock) returnlock = truelet done = () => lock = falseif (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()) returnreturn 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()) // 0p.changeExp(2000)console.log(p.getExp()) // 2000
四、总结
1. JavaScript 重温系列(22篇全) 2. ECMAScript 重温系列(10篇全) 3. JavaScript设计模式 重温系列(9篇全) 4. 正则 / 框架 / 算法等 重温系列(16篇全) 5. Webpack4 入门(上)|| Webpack4 入门(下) 6. MobX 入门(上) || MobX 入门(下) 7. 80+篇原创系列汇总 回复“加群”与大佬们一起交流学习~
点击“阅读原文”查看 80+ 篇原创文章
评论

