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