什么是词法作用域

简单来讲,词法作用域就是定义在词法阶段的作用域,换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里决定的。

遮蔽效应

作用域查找会在找到第一个匹配的标识符时停止,在多层嵌套的作用域中可以定义同名的标识符,这叫做"遮蔽效应"

欺骗词法

欺骗词法作用域会导致性能下降

eval

eval 可以对一段包含代码的字符串进行演算,并借此来修改词法作用域。

非严格模式下,eval会对其所在的词法作用域进行修改,严格模式下,其有自己的词法作用域,不会对所在的词法作用域造成修改。

非严格模式:

1
2
3
4
5
6
    function foo(str) {
        eval(str)
        console.log(b) // b 等于 3
    }
    var b = 2
    foo("var b = 3")

严格模式下:

1
2
3
4
5
6
7
    function foo(str) {
        "use strict"
        eval(str)
        console.log(b) // b 等于 2
    }
    var b = 2
    foo("var b = 3")

with

with 本质上是将一个对象的引用当做作用域来处理,创建了一个新的词法作用域

副作用

这两个机制的副作用是引擎无法在编译时对作用域查找进行优化,因为这两个机制是在运行时动态创建的。