JS作用域

219 阅读5分钟

什么是作用域?

1、作用域可以理解为一个范围盒子这个盒子决定了哪些变量、对象和函数在特定的区域内可以被访问到。
2、作用域也可以堆叠成层次结构,子作用域可以访问父作用域,反过来不行。

作用域分类:全局作用域、函数作用域、块作用域、模块作用域、脚本作用域、Catch 块作用域、包含块作用域、闭包作用域、Eval作用域

全局作用域(Global)

  • 定义:在所有函数之外声明的变量和函数处于全局作用域。在浏览器环境中,全局作用域通常是 window 对象,在 Node.js 环境中是 global 对象。
  • 特点:全局变量在整个程序的任何地方都可以被访问和修改,他生命周期贯穿整个程序的执行过程,会一直占用内存直到程序结束,这可能导致命名冲突,并且如果不小心使用过多的全局变量,会使程序难以维护。

image.png

函数作用域(Local)

  • 定义:当函数被调用时,会创建一个新的函数作用域,在这个作用域内,可以访问函数的参数和在函数内部声明的变量。
  • 特点:只有在该函数内部才能访问这些变量和参数。当函数执行完毕后,函数作用域中的局部变量通常会被垃圾回收机制回收,释放内存空间。这有助于管理内存,并且可以在不同的函数中使用相同名称的变量而不会相互干扰。

image.png

块作用域(Block)

  • 定义:从 ES6 开始引入,由 let 和 const 声明的变量具有块级作用域,由一对花括号 {} 包裹的代码块所形成的作用域,比如在循环、条件语句的代码块等。
  • 特点:let 和 const 声明的变量只在其所在的块级作用域内有效。这避免了变量提升带来的问题,使变量的作用域更加明确,减少错误的发生。

image.png

模块作用域

  • 定义:每个模块都有独立作用域,其内部变量、函数和类默认对外不可见,只有通过特定导出语句(如export)暴露的部分才能被其他模块访问(严格来说,模块作用域是特殊的函数作用域)。
  • 特点:有助于实现模块化开发,提高代码的可维护性和可复用性,避免了全局变量命名冲突,同时可以更好地控制模块内部的实现细节不被外部随意访问。

image.png

脚本作用域(Script)

  • 定义:<script>标签里定义的变量和函数只在该标签范围内有效。多个<script>标签若无特殊交互方式(如模块系统),它们的作用域是分开的。用 let 或 const 声明的全局变量在 Script 范围,可直接使用但不能通过window.xx访问。
  • 特点:多个<script>标签无特别处理时,不同标签内变量与函数可能相互干扰。具体为,若都用var声明或未用letconst限制作用域的同名变量,后加载的会覆盖前面的;函数同理,后定义的同名函数会覆盖前面的。

image.png

image.png

Catch 块作用域(Catch Block)

  • 定义:catch 语句会生成一个特殊的作用域,当发生错误并被 catch 块捕获时,在 catch 语句的括号中声明的错误变量只在这个 catch 块内部有效。
  • 特点:可以在 catch 块中处理错误,而不用担心这个错误变量会影响到外部作用域。一旦 catch 块执行完毕,这个错误变量通常会被垃圾回收。

image.png

包含块作用域(With Block)(不推荐使用)

  • 定义:with 语句可以将一个对象的属性临时添加到作用域链中。例如 with(obj) {... },在这个代码块中,可以直接访问 obj 的属性而无需通过完整的对象引用。
  • 特点:这种作用域可能会导致作用域变得不清晰,并且容易引起错误,因为它模糊了变量的来源,现代 JS 开发中不推荐使用 with 语句。

image.png

闭包作用域(Closure)

  • 定义:当一个函数内部定义了另一个函数时,内部函数可以访问外部函数的变量,形成闭包作用域,内部函数可以记住并访问其外部函数的变量,即使外部函数已经执行完毕。
  • 特点:闭包可以让函数保留对其外部环境的引用,这在需要保持一些状态或者实现私有变量等场景中非常有用。但是使用不恰当,可能会导致内存泄漏,因为外部函数的变量可能会一直被闭包引用而无法被垃圾回收。

image.png

Eval 作用域(不推荐使用)

  • 定义:eval()函数可执行字符串形式的 JS 代码。它在调用时会形成它的作用域并且执行代码,不过会有安全与可维护性问题。在全局作用域调用eval(),代码就影响全局作用域,在函数作用域调用,代码就影响该函数作用域。
  • 特点:由于 eval() 的行为难以预测,并且可能会引入安全风险,现代 JS 开发中应尽量避免使用 eval()。如果必须使用,要非常小心地处理其作用域和潜在的安全问题。

image.png

以上这些都是调试得到的,是 JS 引擎执行代码时得出的真实作用域。