词法绑定与动态绑定的区别

如前所述(see let 避免命名冲突),在词法绑定模式下, 使用 let 创建的局部变量仅在 let 表达式体内有效。 在代码的其他部分,它们拥有其他含义,因此如果在 let 体内 调用别处定义的函数,该函数无法“看见(see)”你创建的局部变量。 (反之,如果调用在 let 体内定义的函数, 该函数则可以看见并修改该 let 表达式的局部变量。)

在动态绑定模式下,规则有所不同:使用 let 时, 创建的局部变量在 let 表达式执行期间全程有效。 这意味着,如果 let 表达式调用了某个函数, 无论该函数定义在何处(甚至在另一个文件中),都能访问这些局部变量。

另一种理解动态绑定下 let 的方式是: 每个变量名都拥有一个全局的绑定“栈”, 每当使用该变量名时,都指向栈顶的绑定。 (你可以将其想象成桌上一叠写有值的纸张。) 使用 let 进行动态绑定时,会将你指定的新绑定压入栈顶, 然后执行 let 函数体。let 函数体执行完毕后, 该绑定会从栈中弹出,恢复 let 表达式之前的绑定(若存在)。