跳转到主内容
极星编程网:以代码为星,赴技术山海!

javascript中闭包的概念是什么_它如何影响变量作用域?

闭包是函数与其词法环境的组合,需同时满足:存在引用外部局部变量的内部函数、该函数被返回或脱离原始上下文;var/let在循环闭包中因作用域机制不同导致输出差异;闭包会阻止捕获变量被垃圾回收,易引发内存泄漏。 闭包不是某种特殊函数,而是函数与其词法环境的组合——只要一个函数在定义时能访问其外层 作用域 中的变量,并且这个函数在定义之外被调用,就形成了闭包。 闭包产生的核心条件 必须同时满足三个条件: 存在一个内部函数(
function
或箭头函数) 该内部函数引用了外部函数的局部变量(非全局、非参数传入) 外部函数返回了这个内部函数(或以其他方式使它脱离原始执行上下文) 缺一不可。只定义不返回,或返回但没保存/调用,都不构成实际起效的闭包。
var
与
let
在闭包中的行为差异 循环中创建多个闭包时,变量声明方式直接影响结果: 立即学习 “ Java免费学习笔记(深入) ”; Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); // 输出 3, 3, 3 } for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 100); // 输出 0, 1, 2 }
原因:
var
声明的
i
是函数作用域共享的,所有定时器回调共用同一个
i
;而
let
每次迭代都绑定独立的绑定记录(binding),每个闭包捕获的是各自迭代中的
j
值。 闭包导致的内存保留问题 闭包会阻止其词法环境中变量被垃圾回收,即使外部函数早已执行完毕: 如果闭包长期存活(如绑定到全局对象、事件监听器、定时器),它所捕获的变量也会一直驻留内存 特别危险的是捕获了大对象(如
document
、大型数组、DOM 节点集合) 调试时可通过 Chrome DevTools 的
Memory
面板 +
Heap Snapshot
查看“
Closure
”条目下的 retained size 常见误用:
addEventListener
中直接写匿名闭包却不提供
removeEventListener
清理路径,导致重复绑定+内存泄漏。 闭包本身没有“副作用”,但它的生命周期和捕获逻辑很容易被忽略——真正难的不是写出闭包,而是判断某个变量是否被意外长期持有。

相关文章