
当一个函数在其定义时的作用域之外执行,并且仍然可以访问当时的变量,这个现象就叫做闭包。
function createCounter() {
let count = 0
return function () {
count++
return count
}
}
const counter = createCounter()
counter() // 1
counter() // 2
createCounter() 执行完后,按理说作用域应该销毁重点:不是函数产生了闭包,而是函数使用了外层作用域的变量,并且在外层作用域之外执行。
export function useUser() {
const user = ref(null)
function setUser(data) {
user.value = data
}
return {
user,
setUser
}
}
useUser 执行完后,本应销毁setUser 仍然在组件里被调用setUser 引用了 useruseUser 的作用域被保留👉 组合式 API = 闭包驱动的设计
这不是巧合,是语言能力直接影响框架设计。
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i)
}, 1000)
}
//输出3,3,3
var i 只有一个作用域
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i)
}, 1000)
}
👉let 为每次循环创建了一个新的词法作用域
👉 每个回调闭包住的是 不同的 i
闭包会延长变量生命周期,
如果引用链一直存在,才可能导致内存无法释放。
Vue 中真正的问题通常是:
不是“闭包的锅”。
function createUser() {
let password = '123456'
return {
check(pwd) {
return pwd === password
}
}
}
JS 没有 private,但闭包就是私有化方案
function useRequest() {
let loading = false
async function run(promise) {
loading = true
try {
return await promise
} finally {
loading = false
}
}
return { run }
}
👉loading 被 run 闭包住
👉 状态与行为天然绑定
useDebounce,闭包在其中起什么作用?