0

0

javascript闭包如何使用_它怎样影响变量的作用域【教程】

夜晨

夜晨

发布时间:2026-01-27 15:55:03

|

285人浏览过

|

来源于php中文网

原创

JavaScript闭包使外部函数变量在调用后仍存活,因其内部函数记住了创建时的词法环境;只要内部函数存在,就能持续访问外部变量,依赖词法作用域与函数对象携带环境,而非引用计数。

javascript闭包如何使用_它怎样影响变量的作用域【教程】

闭包是怎么让外部函数变量在调用后依然存活的

JavaScript 闭包的本质,是内部函数记住了它被创建时所处的词法环境。只要这个内部函数还存在(比如被返回、被赋值给变量、被传入事件监听器),它就能持续访问外部函数的变量,哪怕外部函数早已执行完毕。

关键点在于「词法作用域」+「函数对象携带环境」,不是靠引用计数或特殊标记。这意味着:var 声明的变量、let/const 声明的块级绑定,都能被闭包捕获,但行为略有差异(后者会为每次循环迭代创建独立绑定)。

  • 常见错误现象:for (var i = 0; i console.log(i), 100) 输出三个 3 —— 因为所有回调共享同一个 i 变量,循环结束时 i === 3
  • 修复方式:改用 let i(每次迭代新建绑定),或用立即执行函数包裹 var i,或用 setTimeout 的第三个参数传参
  • 性能影响:闭包会阻止外部函数作用域被垃圾回收,如果闭包长期存在且引用了大对象(如 DOM 节点、大型数组),可能引发内存泄漏

如何正确返回一个带状态的闭包函数

最典型的闭包使用场景是封装私有状态。你不需要暴露变量本身,只暴露能操作它的函数。

function createCounter() {
  let count = 0;
  return {
    increment: () => ++count,
    reset: () => count = 0,
    value: () => count
  };
}

const counter1 = createCounter();
console.log(counter1.value()); // 0
counter1.increment();
console.log(counter1.value()); // 1
  • 每个 createCounter() 调用都生成独立的 count 绑定,counter1counter2 互不影响
  • 不能直接访问 counter1.count —— 它根本不存在于对象上,只存在于闭包环境中
  • 如果返回的是单个函数(如 return () => count++),那它只能做单一操作;返回对象更灵活,但也意味着要管理多个闭包引用同一环境

闭包和 this 绑定容易混淆的点

闭包捕获的是词法作用域里的变量,不包括 thisthis 是运行时决定的,和函数在哪定义无关。所以常有人误以为「闭包能保存 this」,其实不能。

Gambo
Gambo

世界上首个游戏氛围编程智能体

下载

立即学习Java免费学习笔记(深入)”;

  • 错误写法:function foo() { const self = this; return function() { console.log(self.bar); } } —— 这里保存的是 self,不是 this;真正保存 this 需显式绑定
  • 正确做法:用箭头函数(自动继承外层 this)、bind、或在调用前缓存 const that = this
  • Vue/React 类组件中,事件回调常用 handleClick = () => {...} 就是为了避免 this 丢失,这背后也依赖闭包捕获类实例上下文

什么时候不该用闭包——以及替代方案

闭包不是银弹。当逻辑简单、状态无需隔离、或需要频繁创建大量闭包时,它反而增加理解成本和内存开销。

  • 避免在循环中无节制地创建闭包:比如 list.forEach(item => element.addEventListener('click', () => doSomething(item))),如果 list 很大,每个监听器都是独立闭包;可改用事件委托 + datasetevent.target
  • 模块化代码时,ES6 模块本身已提供作用域隔离,不必强行套一层闭包(如 (function(){...})()
  • 现代开发中,class 实例属性 + 方法也能实现类似私有状态的效果(虽然 JS 目前仍靠 #private 字段真正私有),比手动闭包更直观

闭包真正的不可替代性,在于需要「多个函数共享同一份私有状态」且「这份状态不能挂载到对象属性上」的场景——比如防抖函数的定时器 ID、柯里化函数的预置参数、或 Web Worker 通信中的回调队列管理。这些地方,绕不开闭包的环境捕获能力。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
es6新特性
es6新特性

es6新特性有:1、块级作用域变量;2、箭头函数;3、模板字符串;4、解构赋值;5、默认参数;6、 扩展运算符;7、 类和继承;8、Promise。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

103

2023.07.17

es6新特性有哪些
es6新特性有哪些

es6的新特性有:1、块级作用域;2、箭头函数;3、解构赋值;4、默认参数;5、扩展运算符;6、模板字符串;7、类和模块;8、迭代器和生成器;9、Promise对象;10、模块化导入和导出等等。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

195

2023.08.04

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

221

2025.12.24

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2023.11.20

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

71

2025.12.04

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

530

2023.09.20

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

469

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

13

2025.12.06

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue 教程
Vue 教程

共42课时 | 7.2万人学习

Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号