你不了解的JS笔记 - 第一部分 - 词法作用域
以下是读完《你不了解的JS》第一部分第二章后整理的笔记
词法阶段
词法作用域就是定义在词法阶段的作用域,是由写代码时将变量和块作用域写在哪里决定的。
作用域查找会在找到第一个匹配的标识符时停止。
在多层的嵌套作用域中可以定义同名的标识符,这叫做遮蔽效应。
作用域查找始终从运行中所处的最内部作用域开始,逐级向外或者说向上进行,直到遇见第一个匹配的标识符为止。
全局变量会自动称为全局对象的属性,因此可以不直接通过全局对象的词法名称,而是间接的通过对全局对象属性的引用来对其进行访问(window.a),通过这种技术可以访问那些被同名变量所屏蔽的全局变量。
无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定。
词法作用域查找只会查找一级标识符
欺骗词法
eval
eval函数可以接受一个字符串为参数,并将其中的内容视为好像在书写时就存在于程序中这个位置的代码。
在执行eval之后的代码时,引擎并不知道或在意前面的代码是以动态形式插入进来的,并对词法作用域的环境进行修改的,引擎只会如往常地进行词法作用域查找。
在实际情况中,可以非常容易的根据程序逻辑动态的将字符拼接在一起之后再传递进去,eval()通常被用来执行动态创建的代码。
默认情况下,如果eval()中所执行的代码包含一个或多个声明,就会对eval()所处的词法作用域进行修改。
在严格模式的程序中,eval()在运行时有其自己的词法作用域,意味着其中的声明无法修改所在的作用域。
with
with被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。
with可以将一个没有或有多个属性的对象处理为一个完全隔离的词法作用域,因此这个对象的属性也会被处理为定义在这个作用域中的词法标识符。
尽管with块可以将一个对象处理为词法作用域,但是这个块内部正常的var声明并不会被限制在这个块的作用域中,而是被添加到with所处的函数作用域中。
eval函数如果接受了含有一个或多个声明的代码,就会修改其所处的词法作用域,而with声明实际上是根据传递给它的对象凭空创建了一个全新的词法作用域
如果代码中大量使用eval()和with,会导致代码运行变慢。

浙公网安备 33010602011771号