推荐答案
在 JavaScript 中,作用域链(Scope Chain)是指在函数执行时,查找变量的一种机制。每个函数都有一个与之关联的作用域链,这个链决定了函数在查找变量时的顺序。作用域链由当前函数的变量对象(Variable Object)和所有外层函数的变量对象组成。当函数需要访问一个变量时,它会首先在当前函数的变量对象中查找,如果找不到,就会沿着作用域链向上查找,直到全局作用域为止。
本题详细解读
作用域链的构成
当前函数的变量对象:每个函数在执行时都会创建一个变量对象,这个对象包含了函数内部声明的变量、函数参数以及函数内部定义的函数。
外层函数的变量对象:如果当前函数是在另一个函数内部定义的,那么外层函数的变量对象也会被包含在当前函数的作用域链中。
全局变量对象:最外层的作用域是全局作用域,全局变量对象包含了全局范围内声明的变量和函数。
作用域链的查找过程
当函数需要访问一个变量时,JavaScript 引擎会按照以下步骤进行查找:
在当前函数的变量对象中查找:首先在当前函数的变量对象中查找该变量,如果找到则直接使用。
沿着作用域链向上查找:如果在当前函数的变量对象中没有找到该变量,JavaScript 引擎会沿着作用域链向上查找,依次检查外层函数的变量对象,直到找到该变量为止。
全局作用域:如果在所有外层函数的变量对象中都没有找到该变量,JavaScript 引擎会继续在全局变量对象中查找。如果仍然没有找到,则会抛出
ReferenceError错误。
示例代码
// www.javascriptcn.com code example
var globalVar = "I'm global";
function outerFunction() {
var outerVar = "I'm outer";
function innerFunction() {
var innerVar = "I'm inner";
console.log(innerVar); // 输出: I'm inner
console.log(outerVar); // 输出: I'm outer
console.log(globalVar); // 输出: I'm global
}
innerFunction();
}
outerFunction();在这个例子中,innerFunction 的作用域链包含了它自己的变量对象、outerFunction 的变量对象以及全局变量对象。当 innerFunction 访问 innerVar、outerVar 和 globalVar 时,JavaScript 引擎会按照作用域链的顺序依次查找这些变量。
闭包与作用域链
闭包(Closure)是 JavaScript 中一个重要的概念,它与作用域链密切相关。当一个函数内部定义了另一个函数,并且内部函数引用了外部函数的变量时,就会形成闭包。闭包会保留对外部函数作用域的引用,即使外部函数已经执行完毕,内部函数仍然可以访问外部函数的变量。
// www.javascriptcn.com code example
function outerFunction() {
var outerVar = "I'm outer";
function innerFunction() {
console.log(outerVar); // 输出: I'm outer
}
return innerFunction;
}
var closure = outerFunction();
closure();在这个例子中,innerFunction 形成了一个闭包,它保留了对外部函数 outerFunction 的作用域的引用。即使 outerFunction 已经执行完毕,innerFunction 仍然可以访问 outerVar。