作用域
作用域在编程语言中,它是控制着变量与参数的可访问性和生命周期。
作用域这个东西呢,可以假设它是一个采集工人,专注于收集和维护所有声明的标识符(变量),并且将标识符组成一系列的查询,并实现一套规则来管理标识符,确定执行环境(执行上下文)对标识符的使用权限。
1 | function foo () { |
块级作用域
在JS函数中的var声明,其作用域是函数体的全部,在ES6之前并没有块级作用域的说法,在ES5中只有全局作用域和函数作用域。
大多数像C语言的语言都拥有块级作用域,就是在一个代码块中(在一对花括号中的语句)定义的所有变量在代码块的外部是不可访问的,定义在代码块中的变量会在代码块执行完毕后会释放掉。
在ES6中的新特性:let、const提供了块级作用域。
1 | if (true) { |
变量提升(Hoisting)
直觉上会认为JavaScript代码在执行时是由上到下一行一行执行的。但实际上并不完全正确,有一种特殊情况会导致这个假设是错误的。
考虑下面的代码
1 | a = 2; |
这种写法固然是不推荐的,但它却正确地输出出来,到底是为什么呢。
再看看一下代码1
2console.log(a) // a => undefined
var a = 2
搞明白这个问题,要了解引擎和编译器的机制。
引擎在解释JavaSript代码之前首先会对其进行编译,编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。
因此,正确的思路是:在编译的时候,变量和函数在内的所有声明都会在任何代码被执行之前被处理。