结论
当函数可以记住并访问所在的词法作用域,即使函数实在当前词法作用域之外执行,这时就产生了闭包。
什么是词法作用域?
词法作用域意味着作用域是由书写代码时函数声明的位置来决定的。编译的词法分析阶段基本能够置到全部的标识符在哪里以及时如何声明的,从而能够预测再执行过程中如何对他们进行查找。
编译?(编译器的工作)
在传统的编译语言的流程中,程序的一段源代码在执行之前会经历三个步骤,统称为“编译”。
1.分词,词法分析
2.解析,语法分析
3.代码生成
比起那些编译过程只有三个步骤的语言的编译器,JavaScript引擎要复杂的多。例如,在语法分析和代码生成阶段有特定的步骤对运行性能进行优化,包括对冗余元素进行优化等。
什么是作用域?
作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。如果查找的目的是对变量进行赋值,那么就会使用LHS查询;如果是获取变量的值,就会使用RHS查询。
什么是LHS查询,RHS查询?
当变量出现在赋值操作符的左侧时进行LHS查询,出现在右侧时进行RHS查询。RHS查询与简单地查找某个变量的值别无二致,而LHS查询则是试图找到变量的容器本身,从而可以对其赋值。
LHS查询和RHS查询都会在当前作用域中开始,如果有需要(也就是说没有找到所需的标识符),就会向上级作用域继续查找目标标识符,这样每次上升以及作用域(一层咯),最后抵达全局作用域(顶层),无论找没找到都将停止。
不成功的RHS引用会道指抛出Reference异常。不成功的LHS引用会导致自动隐式创建一个全局变量(非严格模式下),该变量使用LHS引用的目标标识符,或者抛出Reference异常(严格模式下)。
作用域单元、块级作用域?
函数是JavaScript中最常见的作用域单元。声明再一个函数内部的变量或者函数会再所处的作用域中隐藏起来。但函数不是唯一的作用域单元。块作用域值得是变量和函数不仅可以属于所处的作用域,也可以属于某个代码块(通常是指{..}内部)