深入理解JavaScript高级之词法作用域和作用域链
什么是词法作用域
词法作用域是指JavaScript代码的作用域是基于源代码中变量和函数声明的位置来确定的,而不是基于运行时的调用栈。换言之,词法作用域与代码的声明位置有关。
例如,下面的代码示例中,bar
函数在foo
函数内部定义,因此它的作用域(也称为“词法环境”)包含了foo
函数范围内的变量,即x
变量。
function foo() {
var x = 1;
function bar() {
console.log(x);
}
bar();
}
foo(); // 输出1
作用域链
每个JavaScript函数都与一个“作用域链”相关联,该作用域链是由当前执行环境和所有包含它的外部环境中的变量对象组成的。变量对象包含了在当前执行环境中定义的变量,以及在父级执行环境中定义的变量。当需要访问一个变量时,JavaScript引擎会沿着作用域链向上查找,直到找到该变量为止。
例如,下面的代码示例中,bar
函数在foo
函数内部定义,因此它的作用域链包含了foo
函数的变量对象和全局变量对象。当bar
函数需要访问x
变量时,JavaScript引擎会从bar
函数的作用域开始向上查找,直到找到该变量为止。
var x = 1;
function foo() {
var x = 2;
function bar() {
console.log(x);
}
bar();
}
foo(); // 输出2
示例说明
示例1
function test() {
var x = "hello";
function innerTest() {
console.log(x);
}
x = "world";
return innerTest;
}
var fn = test();
fn(); // 输出"world"
在上述示例中,innerTest
函数定义在test
函数内部,但它在return
语句中被返回,这就导致它可以在test
函数的外部被调用。innerTest
函数的作用域链中包含了test
函数的变量对象和全局变量对象。当innerTest
函数被调用时,JavaScript引擎会从innerTest
函数的作用域对象开始向上查找,直到找到x
变量为止。由于x
变量在test
函数内部被重新赋值为"world",因此最终输出的结果为"world"。
示例2
var a = 1;
var b = 2;
function outer() {
var a = 3;
function inner() {
console.log(a+b);
}
return inner;
}
var fn = outer();
fn(); // 输出5
在上述示例中,inner
函数在outer
函数内部定义,因此它的作用域链包含了outer
函数的变量对象和全局变量对象。当inner
函数被调用时,JavaScript引擎会从inner
函数的作用域对象开始向上查找,直到找到a
和b
变量为止。由于a
变量在outer
函数内部被重新赋值为3,而b
变量属于全局变量,因此最终输出的结果为5。
总结
词法作用域和作用域链是JavaScript中非常重要的概念,对于理解函数的作用域和变量的作用范围有着关键的作用。理解这些概念能够帮助我们更好地编写和调试JavaScript代码。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解JavaScript高级之词法作用域和作用域链 - Python技术站