Javascript中的闭包

1、什么是闭包

当一个函数在其定义时的作用域之外执行,并且仍然可以访问当时的变量,这个现象就叫做闭包。

javascript 复制代码
function createCounter() {
  let count = 0

  return function () {
    count++
    return count
  }
}

const counter = createCounter()
counter() // 1
counter() // 2
  • createCounter() 执行完后,按理说作用域应该销毁

  • 但返回的函数 仍然引用了 count

  • JS 引擎发现:

    👉 这个作用域不能回收

  • 于是形成了一个 被"保活"的作用域 ------ 这就是闭包

重点:不是函数产生了闭包,而是函数使用了外层作用域的变量,并且在外层作用域之外执行。

2、vue中的闭包案例

javascript 复制代码
export function useUser() {
  const user = ref(null)

  function setUser(data) {
    user.value = data
  }

  return {
    user,
    setUser
  }
}
  • useUser 执行完后,本应销毁

  • setUser 仍然在组件里被调用

  • setUser 引用了 user

  • 所以:useUser 的作用域被保留

👉 组合式 API = 闭包驱动的设计

这不是巧合,是语言能力直接影响框架设计

3、为什么 for + setTimeout 会"翻车"

javascript 复制代码
for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}
//输出3,3,3
  • var i 只有一个作用域

  • 所有回调 共享同一个 i

  • 回调执行时,循环早就结束了

javascript 复制代码
for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}

👉let 为每次循环创建了一个新的词法作用域

👉 每个回调闭包住的是 不同的 i

**4、**闭包 ≠ 内存泄漏

闭包会延长变量生命周期,
如果引用链一直存在,才可能导致内存无法释放。

Vue 中真正的问题通常是:

  • 全局事件没解绑

  • 定时器没清理

  • 引用被缓存到单例中

不是"闭包的锅"。

5、用闭包实现"私有变量"

javascript 复制代码
function createUser() {
  let password = '123456'

  return {
    check(pwd) {
      return pwd === password
    }
  }
}

JS 没有 private,但闭包就是私有化方案

**6、**Vue 业务里的真实闭包模式

javascript 复制代码
function useRequest() {
  let loading = false

  async function run(promise) {
    loading = true
    try {
      return await promise
    } finally {
      loading = false
    }
  }

  return { run }
}

👉loading 被 run 闭包住

👉 状态与行为天然绑定

7、思考

  • 为什么 setup 执行一次,但状态可以长期存在?

  • 闭包和模块作用域有什么相同与不同?

  • 如果一个闭包持有一个很大的对象,什么时候会释放?

  • 为什么 hooks / composables 天然适合用闭包实现?

  • 如果让你写一个 useDebounce,闭包在其中起什么作用?

相关推荐
tang7778934 分钟前
爬虫如何绕过绕过“5秒盾”Cloudflare:从浏览器指纹模拟到Rust求解之不完全指南
开发语言·爬虫·rust·cloudflare
Yuer202538 分钟前
什么是 Rust 语境下的“量化算子”——一个工程对象的最小定义
开发语言·后端·rust·edca os·可控ai
2501_9481953440 分钟前
RN for OpenHarmony英雄联盟助手App实战:符文配置实现
javascript·react native·react.js
hqwest41 分钟前
码上通QT实战26--系统设置01-系统设置布局
开发语言·qt·qss·qt基础控件·qt布局控件·qt表格控件
薛定谔的猫198242 分钟前
llama-index Embedding 落地到 RAG 系统
开发语言·人工智能·python·llama-index
rocky1911 小时前
网页版时钟
前端·javascript·html
jghhh011 小时前
传递对准MATLAB仿真程序
开发语言·matlab
一只小阿乐2 小时前
vue-web端实现图片懒加载的方
前端·javascript·vue.js
2501_944521002 小时前
rn_for_openharmony商城项目app实战-商品评价实现
javascript·数据库·react native·react.js·ecmascript·harmonyos
编程武士2 小时前
Python 各版本主要变化速览
开发语言·python