JS之作用域
1.作用域是什么?
首先要知道一段JS程序执行过程中,有哪些角色在起作用:
- 引擎
- 负责JS程序的编译与执行过程
- 编译器
- 负责语法分析及代码生成
- 作用域
- 负责收集并维护所有声明的变量,并确定这些变量的访问权限
示例:
var a = 2
这段代码是如何执行的:
- 编译时:
编译器
在当前作用域声明一个变量a - 运行时:
引擎
在作用域中查找该变量a,找到了就赋值为2;找不到这个变量a就抛出异常。
可以看到,JS代码执行过程都是围绕着作用域的。js代码中的变量都是放在作用域中的。
2. JS有哪些作用域
JS有两种常见作用域:
- 全局作用域
- 函数作用域
函数作用域就是一段代码如果用函数进行包裹,那么函数外界就无法访问到这个函数的作用域。
还有一种作用域就是块作用域。如 if(){ .. }
,for(){ .. }
,{..} 代码块
等这种都是属于块作用域,但是使用var
关键字在块作用域中声明的变量,却是可以在这个块作用域外访问到的,因此会有污染全局作用域变量的风险。不过要解决这个问题可以在块作用域中使用let/const
关键字来声明变量。
可以将作用域想象成下面这种模型:
这里就包含了三层的作用域:
① 全局作用域,只有一个标识符:foo
② foo的作用域,有三个标识符:a、bar、b
③ bar的作用域,只有一个标识符:c
一个变量的作用域在哪里取决于其在哪里定义的(注意块级作用域中用var声明的变量不属于这个块级作用域,它属于全局作用域)。
引擎在查找某个变量时会由内而外向最外层作用域查找这个变量,如果都没找到就抛出ReferenceError
异常。