一、作用域
作用域是变量的可访问范围,即作用域控制着变量与函数的可见性和生命周期。(参考js垃圾回收)作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
常见的作用域主要分为几个类型:全局作用域(global/window)、局部作用域、块级作用域、动态作用域。
1.全局作用域
在代码中任何地方都能访问到的对象拥有全局作用域,
(1)最外层的函数(在任意位置都能访问)和最外层的变量拥有全局作用域
(2)未经定义而直接赋值的变量自动被声明为拥有全局作用域
(3)所有window对象的属性拥有全局作用域
全局作用域有个弊端:如果我们写了很多行 JS 代码,变量定义都没有用函数包括,那么它们就全部都在全局作用域中。这样就会 污染全局命名空间, 容易引起命名冲突。
2.局部作用域
局部作用域一般只能在固定的代码片段中才能访问,如函数内部的变量(函数作用域)函数内部访问
3.块级作用域
块级作用域可通过新增命令let和const声明,所声明的变量在指定块的作用域外无法被访问。块级作用域在如下情况被创建:
在一个函数内部在一个代码块(由一对花括号包裹)内部
注意:块语句(大括号“{}”中间的语句),如 if 和 switch 条件语句或 for 和 while 循环语句,不像函数,它们不会创建一个新的作用域。
4.动态作用域
只能在执行阶段才能决定变量的作用域,那就是动态作用域(this)
动态作用域规则依赖的是程序执行时的函数调用顺序
二、作用域链
由多级作用域连续引用形成的链式结果
掌管一切变量的使用顺序: 先在局部找,没有,就延作用域向父级作用域找,没有,就延作用域向父级作用域找 ..,直到找到window;
引申:词法作用域也称静态作用域
词法作用域是由编写代码时将变量和作用域写在哪里来决定的,即词法作用域的定义过程发生在代码的书写阶段,因而词法分析器处理代码时会保持作用域不变。无论函数在哪里被调用,也无论它如何被调用,他的词法作用域都只由函数声明时所处位置决定(即创建的位置)
JavaScript默认采用的是静态作用域,也称为词法作用域,