1、写在前面
程序代码的作用域,限制了在其范围里面的变量、函数的可访问性。而作用域一般包含动态作用域、静态作用域、
块作用域和函数作用域。JavaScript采用的是静态作用域,也称为词法作用域,在此基础上结合块作用域和函数作用域。
2、静态作用域
示例代码
var func;
function f() {
var x = 100;
return function g() {
console.log(x);
};
}
var x = 200;
func = f();
func(); // 从函数g定义所在作用域开始,往外层查找
JavaScript 程序执行时,首先调用f()将其返回值赋值给func,然后执行func(),最后输出值是100。为什么不是输出值200?
这个关键的原因就是使用静态作用域了。静态作用域的关键点是:变量和函数的作用域,在定义的时候就已经决定了。
上面代码执行func()时,即跳转到执行g()。此时,首先在g()函数里面搜索变量x的value,没有;再次,在上一层
作用域f()函数里面搜索变量x的value,成功,即输出100。
3、动态作用域
示例代码
#!/bin/bash
value=1;
function inCall () {
echo $value;
}
function outCall () {
local value=2;
inCall;
}
outCall; ## 输出 2
bash脚本语言采用的是动态作用域执行,当调用outCall函数时,在当前的作用域value变量为2,所以影响到inCall输出值
在执行时动态修改为2。
4、块作用域
for (let i = 0; i < 3; i++) {
console.log(i);
}
console.log(i); // ES6后let声明变量i只能在{}可以访问
5、函数作用域
function f() {
var d = 4;
console.log(d);
}
f();
//console.log(d);
6、写在最后
看如下一个代码片段,JavaScript的静态作用域,是如何做到前一个函数的执行完成,其内部声明的子函数
还能访问到之前环境的变量?
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();