精读《你不知道的JavaScript》上卷-I-第2章词法作用域

235 阅读2分钟

I-第2章 词法作用域

词法作用域就是定义在词法阶段的作用域。

词法作用域意味着作用域是由书写代码时函数声明的位置来决定的。编译的词法分析阶段基本能够知道全部标识符在哪里以及是如何声明的,从而能够预测在执行过程中如何对它们进行查找。

无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定。


在多层的嵌套作用域中可以定义同名的标识符,这叫作“遮蔽效应”(内部的标识符“遮蔽”了外部的标识符)。

全局变量会自动成为全局对象(比如浏览器中的 window 对象)的属性,因此可以不直接通过全局对象的词法名称,而是间接地通过对全局对象属性的引用来对其进行访问window.a,通过这种方式可以访问那些被同名变量所遮蔽的全局变量。

但非全局的变量如果被遮蔽了,无论如何都无法被访问到。


欺骗语法

JavaScript 中有两个机制可以“欺骗”词法作用域:eval(..) 和 with。

前者可以对一段包含一个或多个声明的“代码”字符串进行演算,并借此来修改已经存在的词法作用域(在运行时)。

后者本质上是通过将一个对象的引用当作作用域来处理,将对象的属性当作作用域中的标识符来处理,从而创建了一个新的词法作用域(同样是在运行时)。

这两个机制的副作用是引擎无法在编译时对作用域查找进行优化,因为引擎只能谨慎地认为这样的优化是无效的。会导致性能下降。不要使用它们。

↓↓↓↓↓↓

上一章

第1章-作用域是什么