关于Javascript静态作用域的一些心得。
之前在看JS大牛BYVoid的<<NodeJS开发指南一书>>时, 学习到了最能说明Javascript静态作用域特性的代码, 如下:
var scope = "global";
function f1() {
console.log(scope);
}
f1() // output: global
function f2() {
scope = "f2"
f1();
}
f2(); // output: global
第一次输出“global”,
是因为f1()函数找到父级执行作用域下(全局作用域)有定义全局变量scope = “global“。
第二次输出”global“,
因为JS静态作用域链的特性使得作用域链是在函数定义时候被决定的,而不是在调用时候被决定的。
所以在f2()函数中执行f1()函数的时候,f1()函数的父级作用域仍然是全局作用域,所以依然会输出“global”。
那如何在不改变f1函数的结构和定义的情况下,使得在f2函数中输出的scope的变量的值可以是“f2”呢
使用with。
var scope = "global";
function f1() {
console.log(scope);
}
f1() // output: global
function f2() {
scope = "f2"
with(scope) {
f1();
}
}
f2(); // output: f2
with会改变其范围内的作用域链。
这里with把在其范围内的f1()函数的执行作用域链的父级作用域更改为了自己,
所以在执行f1()函数时,找到父级作用域链中scope定义为“f2”,
因此加入with后,第二次可以输出“f2”。