JS 函数的执行环境和作用域链的深入解析
1. 执行环境
在 JavaScript 中,执行环境是指一段可执行代码的运行环境,有全局执行环境和函数执行环境两种。
全局执行环境
全局执行环境是在浏览器中直接打开网页时就会创建的执行环境,它是最顶层的环境。全局执行环境中定义的变量和函数被称为全局变量和全局函数,它们可以在程序的任何地方被访问和修改。
示例代码:
var a = 'Hello World';
function sayHello() {
alert(a);
}
sayHello(); // 输出 Hello World
在上面的代码中,变量a和函数sayHello()
都定义在全局执行环境中,所以它们可以被main函数中的代码所访问。
函数执行环境
除全局执行环境外,JavaScript还有函数执行环境。当一个函数被执行时,就会创建一个函数执行环境,这个执行环境也可以称为活动对象。这个执行环境被用来存储函数内部的局部变量、函数参数和内部函数等。
示例代码:
function main() {
function sayHello() {
var name = 'world';
alert("Hello, " + name);
}
sayHello();
}
main(); // 输出 Hello, world
在上面的代码中,函数sayHello()
内部定义了一个局部变量name
,这个变量只能在函数内部被访问。在函数被调用时,就会创建一个函数执行环境。在函数执行完毕之后,这个函数执行环境就会被销毁,这个局部变量也会被删除。
2. 作用域链
作用域指的是程序在运行过程中,可以访问和修改的变量的集合。JavaScript中的作用域是静态作用域,也就是说变量的作用域取决于它们在程序中定义的位置,而不是在程序中执行的位置。
作用域链指的是一个函数执行环境中所有可访问的作用域的链表,链表的顶部是本地的活动对象,链表的底部是全局对象。作用域链实际上是在函数定义的时候就已经确定了。
示例代码:
var a = 'Global'; // 全局变量
function fun1() {
var a = 'Local'; // 局部变量
function fun2() {
alert(a); // 输出 Local
}
fun2();
}
fun1();
在上面的代码中,当函数fun2()
需要访问局部变量a
时,首先在自己的活动对象中查找,如果找到了就不再继续向上查找,如果没有找到,就开始向上查找整个作用域链,直到找到全局对象才停止查找。
总结
JavaScript的执行环境和作用域链是实现变量访问和作用域的关键机制。全局执行环境和函数执行环境分别对应着全局作用域和函数作用域,作用域链指的是一个函数执行环境中所有可访问的作用域的集合。可以通过声明变量、定义函数等方式来改变作用域链。