您的位置:首页 > 新闻 > 会展 > 深圳平台推广_天津seo选天津旗舰科技a_百度seo排名软_西点培训

深圳平台推广_天津seo选天津旗舰科技a_百度seo排名软_西点培训

2025/1/9 9:43:42 来源:https://blog.csdn.net/m0_73574455/article/details/145018620  浏览:    关键词:深圳平台推广_天津seo选天津旗舰科技a_百度seo排名软_西点培训
深圳平台推广_天津seo选天津旗舰科技a_百度seo排名软_西点培训

 1. 什么是闭包?

 简单理解:闭包就是一个函数能够记住并访问它的外部变量,即使这个函数在其他地方执行

 专业定义:闭包是一个函数以及其周围状态(词法环境)的引用的组合

2. 基本闭包示例

function createCounter() {let count = 0  // 这个变量被内部函数所引用,形成闭包return function() {count++  // 内部函数可以访问外部函数的变量console.log(count)}
}const counter = createCounter()
counter()  // 输出: 1
counter()  // 输出: 2
// 解释:即使 createCounter 已经执行完毕,但 count 变量仍然存在且能被访问
// 因为返回的函数形成了一个闭包,保持着对 count 的引用

 3. 闭包的实际应用场景

3.1 数据私有化

function createBankAccount(initialBalance) {let balance = initialBalance  // 私有变量return {// 只提供特定的方法来访问和修改余额getBalance: function() {return balance},deposit: function(amount) {balance += amountreturn balance},withdraw: function(amount) {if (amount > balance) {return '余额不足'}balance -= amountreturn balance}}
}const account = createBankAccount(1000)
console.log(account.getBalance())  // 1000
account.deposit(500)  // 1500
account.withdraw(200)  // 1300
// account.balance  // undefined,无法直接访问 balance

3.2 函数工厂(创建具有特定行为的函数)

function multiply(x) {return function(y) {return x * y}
}const multiplyByTwo = multiply(2)
const multiplyByFive = multiply(5)console.log(multiplyByTwo(3))  // 6
console.log(multiplyByFive(3))  // 15

3.3 事件处理和回调

function setupHandler() {let clickCount = 0// 这个函数形成闭包,记住了 clickCountreturn function handler() {clickCount++console.log(`按钮被点击了 ${clickCount} 次`)}
}const handleClick = setupHandler()
// 每次点击都能正确显示点击次数,因为 clickCount 被保存在闭包中

4. 闭包可能导致的问题

4.1 内存泄漏

// 4.1 内存泄漏
function createLeak() {const largeData = new Array(1000000)  // 大量数据return function() {// 使用了外部变量,导致 largeData 无法被垃圾回收console.log(largeData.length)}
}

4.2 循环中的常见错误

// 4.2 循环中的常见错误
// 错误示例
for(var i = 0; i < 3; i++) {setTimeout(function() {console.log(i)  // 会输出三次 3}, 1000)
}// 正确做法
for(let i = 0; i < 3; i++) {setTimeout(function() {console.log(i)  // 会输出 0, 1, 2}, 1000)
}

5.隆重介绍闭包在实际开发中的一些重要应用

1. 防抖 (Debounce)

// 1. 防抖 (Debounce)
// 作用:将多次连续的函数调用合并成一次,常用于搜索框输入、窗口调整等
function debounce(fn, delay) {let timer = null  // 使用闭包保存定时器return function(...args) {// 每次触发时,清除之前的定时器if (timer) clearTimeout(timer)// 设置新的定时器timer = setTimeout(() => {fn.apply(this, args)}, delay)}
}// 防抖使用示例
const handleSearch = debounce(function(keyword) {console.log('搜索关键词:', keyword)
}, 300)// 用户快速输入时,只会在最后一次输入后300ms才执行搜索
searchInput.addEventListener('input', (e) => handleSearch(e.target.value))

2. 节流 (Throttle)

// 作用:限制函数在一定时间内只能执行一次,常用于滚动事件、按钮点击等
function throttle(fn, interval) {let lastTime = 0  // 使用闭包保存上次执行时间return function(...args) {const nowTime = Date.now()// 如果距离上次执行的时间大于间隔,则执行函数if (nowTime - lastTime >= interval) {fn.apply(this, args)lastTime = nowTime}}
}// 节流使用示例
const handleScroll = throttle(function() {console.log('页面滚动位置:', window.scrollY)
}, 200)// 滚动时每200ms最多执行一次
window.addEventListener('scroll', handleScroll)

3. 缓存函数结果 (Memoization)

// 3. 缓存函数结果 (Memoization)
// 作用:缓存计算结果,避免重复计算
function memoize(fn) {const cache = {}  // 使用闭包保存缓存return function(...args) {const key = JSON.stringify(args)if (key in cache) {console.log('从缓存中获取结果')return cache[key]}console.log('计算新的结果')const result = fn.apply(this, args)cache[key] = resultreturn result}
}// 缓存函数使用示例
const expensiveFunction = memoize((n) => {// 假设这是一个耗时的计算return new Promise(resolve => {setTimeout(() => {resolve(n * 2)}, 1000)})
})

4. 创建自增ID生成器

// 4. 创建自增ID生成器
// 作用:生成唯一ID
function createIdGenerator() {let id = 0  // 使用闭包保存idreturn function() {return ++id}
}const generateId = createIdGenerator()
console.log(generateId())  // 1
console.log(generateId())  // 2

5. 创建一次性执行的函数 (Once)

// 5. 创建一次性执行的函数 (Once)
// 作用:确保函数只执行一次,常用于初始化操作
function once(fn) {let called = false  // 使用闭包记录是否调用过let resultreturn function(...args) {if (!called) {result = fn.apply(this, args)called = true}return result}
}// 一次性函数使用示例
const initialize = once(() => {console.log('初始化操作,只执行一次')return { data: 'initialized' }
})

6. 柯里化 (Currying)

6. 柯里化 (Currying)
// 作用:将多参数函数转换为一系列单参数函数
function curry(fn) {return function curried(...args) {if (args.length >= fn.length) {return fn.apply(this, args)}return function(...moreArgs) {return curried.apply(this, args.concat(moreArgs))}}
}// 柯里化使用示例
const add = curry((a, b, c) => a + b + c)
console.log(add(1)(2)(3))  // 6
console.log(add(1, 2)(3))  // 6

总结:

1.闭包的本质是函数能够访问其定义时的作用域

2.闭包主要用于:

  • 数据私有化
  • 状态维护
  • 函数工厂
  • 回调函数

3. 闭包的优点:

  • 可以访问外部变量
  • 可以维护私有变量
  • 可以实现数据封装

4.闭包的注意事项:

  • 可能造成内存泄漏
  • 创建太多闭包可能影响性能
  • 需要注意变量作用域

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com