◆
JavaScript 作用域嵌套与作用域链详解
什么是作用域嵌套
当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。因此,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止。
示例
如下代码,对 b 进行的 RHS 引用无法在函数 foo 内部完成,但可以在上一级作用域(在这个例子中就 是全局作用域)中完成。
function foo(a) {
console.log(a + b);
}
var b = 2;
foo(2);
函数被调用之前作用域链已经存在
fxAge = 'fx is 18 years old';
function fxFn() {
console.log(fxAge); // undefined
var fxAge = 'fx is 8 years old';
var fxSub = 'fx is 25 years old';
console.log(fxAge); // fx is 8 years old
function fxFnSub() {
console.log(fxSub); // fx is 25 years old
console.log(fxAge); // fx is 8 years old
}
return fxFnSub;
}
var fx = fxFn();
fx();
如下代码,在函数被执行之前已经创建了两条作用域链:
- 全局作用域 ->
fxFn函数作用域 - 全局作用域 ->
fxFnSub函数作用域
var fx = 'fx is a great girl';
function fxFn() {
// 输出的是全局作用域的 fx:fx is a great girl
console.log(fx);
}
function fxFnSub() {
var fx = 'fx is 18 years old';
return fxFn;
}
var myFx = fxFnSub();
myFx();
// x 的作用域是全局作用域,全局作用域中没有对 a 进行定义
var x = function () {
console.log(a);
};
function y(f) {
var a = 2;
f();
}
y(x); // ReferenceError: a is not defined
综上示例,可以理解为
函数的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。
遍历嵌套作用域链规则
引擎从当前的执行作用域开始查找变量,如果找不到, 就向上一级继续查找。当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都会停止。
作用域链
如图所示,这个建筑代表程序中的嵌套作用域链。第一层楼代表当前的执行作用域,也就是你所处的位置。建筑的顶层代表全局作用域。

LHS 和 RHS 引用都会在当前楼层进行查找,如果没有找到,就会坐电梯前往上一层楼,如果还是没有找到就继续向上,以此类推。一旦抵达顶层(全局作用域),可能找到了你所需的变量,也可能没找到,但无论如何查找过程都将停止。

还没有留言,来发表第一条吧~