作用域
作用域就是一个变量可以使用的范围
,主要分为全局作用域和函数作用域以及块级作用域(ES6新增)。
函数作用域是js通过函数创建的一个独立作用域,只能在函数内部访问,函数可以嵌套,所以作用域也可以嵌套,形成作用域链。
我们一般将作用域分成:
全局作用域
(var声明)函数作用域(也叫局部作用域)
(函数内声明,只能在函数内调用)块级作用域
(ES6新增的,由大括号包裹(let, const 声明),比如:if(){},for(){}等)
词法作用域
词法作用域,又叫静态作用域
,变量被创建
时就确定好了,而非执行阶段确定的。也就是说我们写好代码时它的作用域就确定了,JavaScript 遵循的就是词法作用域
作用域链
当在 Javascript 中使用一个变量
的时候,首先 Javascript 引擎会尝试在当前作用域
下去寻找该变量,如果没找到,再到它的上层作用域
寻找,以此类推直到找到
该变量或是已经到了全局作用域
。
如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明
该变量(非严格模式下)或是直接报错
。
当前作用域外的变量都是自由变量
,一个变量在当前作用域没有定义,但是被使用了,就会向上级作用域,一层一层依次查找,直至找到为止,如果全局作用域都没有找到这个变量就会报错。这个自由变量查找的过程
就是作用域链
。
作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链,我们可以访问到外层环境的变量和函数, 简单来说:内部函数访问外部函数的变量这种链式查找的机制被称为作用域链
。
这里拿《你不知道的Javascript(上)》中的一张图解释把作用域比喻成一个建筑,这份建筑代表程序中的嵌套作用域链,第一层代表当前的执行作用域,顶层代表全局作用域