作用域:作用域决定了变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期
javascript中的的两种作用域:全局作用域和局部作用域
全局作用域
拥有全局作用域的对象可以再代码的任何地方访问到,在js中一般有以下几种情形拥有全局作用域
- 最外层函数以及最外层变量
- 未定义直接赋值的变量(由于变量提升使之成为全局变量)
函数中定义的变量,不添加var关键字会造成变量提升,这个变量会成为一个全局变量
局部作用域
- 函数作用域
定义在函数中的变量就在函数作用域中,函数每次调用都有一个不同的作用域,意味着同名变量可以再不同的函数中。因为这些变量绑定在不同的函数中,拥有不同作用域,彼此之间不能访问
- 块级作用域
ES6新增let和const命令,用来创建块级作用域变量,使用let命令声明的变量只能在let命令所在的代码块内有效
块级作用域特点:1.变量不会提升到代码块顶部且不允许从外部访问块级作用域内部变量
2.不允许反复声明
javascript是如何执行的?
分析阶段
分析函数参数
分析变量声明
分析函数声明
执行阶段
引擎询问作用域,作用域是否含有x的变量
如果作用域有x变量,引擎会使用这个变量
如果作用域中没有,引擎会继续查找,到了最后都没找到这个变量,引擎会抛出错误
LHS和RHS查询特殊说明
LHS = 变量的赋值或写入内存,想象为将文本保存到硬盘中
RHS = 变量查找或从内存中读取,想象为从硬盘打开文本文件
LHS和RHS特性
都会在所有作用域中查询
严格模式:找不到所需的变量时,引擎会抛出RefernceError异常
非严格模式下,LHS稍微比较特殊,会自动创建一个全局变量
查询成功时, 如果对变量的值进行不合理的操作,如:对一个非函数类型的值进行函数调用,引擎会抛出TypeError异常
作用域链总结
在函数执行的时候,会在当前函数内部作用域查找变量,如果没有找到会往外层作用域找,直到全局作用域.