【总结】JavaScript 变量作用域和闭包

3,525 阅读1分钟
  1. Lexical Environment
  • 每个运行的函数、代码块或脚本都有一个关联的 Lexical Environment 对象,它用来存储局部变量和函数声明。
  • Lexical Environment 有两个组成部分:Environment Record(存储变量)和对外部 Lexical Environment 的引用。
  • 函数在执行时会生成一个内部的 Lexical Environment 来存储局部变量和参数。
  1. 变量
  • 变量实际上就是 Lexical Environment 的属性。读取/修改变量就是读取/修改这个对象的属性。
  • 函数声明会被立即初始化,但 let/const 变量要到声明后才能读取。
  • 块级作用域 - 在 {} 内声明的变量只在块内可见。
  1. 嵌套函数
  • 嵌套函数可以访问外部函数的变量,这使其可以封装外部变量。
  • 嵌套函数会通过 Environment 属性记住它被创建的位置,所以它总能访问该位置的外部变量。
  1. 闭包
  • 闭包是可以记住外部变量并访问这些变量的函数。
  • JavaScript 中所有函数都是天然的闭包,它们通过 Environment 属性实现。
  1. 垃圾回收
  • 如果嵌套函数被引用,则外部 Lexical Environment 不会被回收。
  • 但是如果外部变量没有被嵌套函数使用,引擎会对其进行优化,使其无法在嵌套函数中访问。
  1. 其他
  • 理解 Lexical Environment 和闭包的工作原理可以更好地编写 JavaScript 代码。
  • 嵌套函数和闭包在组织代码和封装变量方面很有用。
  • 变量优化可能会使开发调试变得困难。