JavaScript 执行上下文及作用域链
1. 之前在脑子比较混乱的时候写的一段水文:https://www.cnblogs.com/twinkleG/p/15362246.html 现在回过头来看有点没意义,重新组织一下语言。
2. 红宝书 P88
(1)JavaScript 中作用域也叫做执行上下文,变量和函数所处的上下文决定了它们能够访问哪些数据。每个上下文都会有一个与之相关联的变量对象,这个变量对象存储着你定义在这个上下文的所有变量和函数。
(2)全局上下文就是最外层的上下文,我们一般用 var 定义的全局变量和函数都会处于全局上下文中,在浏览器中,全局上下文就是我们所说的 window 对象,因此可以通过 window 对象访问定义的全局变量和函数。但ES6 中 let、const 定义的变量和函数不可以被 window.xxx 访问到。
(3)一个上下文的代码在被执行完后,这个上下文就会被销毁,与此同时,定义在此上下文内的所有变量和函数也会被销毁。
(4)当一个函数在执行时,这个函数的上下文就会被推入上下文栈中,当函数执行完,这个函数的上下文会被弹出栈,JavaScript 就是通过上下文栈控制程序的执行的。
(5)在一个上下文执行时,这个上下文的变量对象会创建作用域链,并且处于作用链的最前端,在访问变量或函数时,先从作用域链最前端寻找,若未找到则去这个上下文的外层上下文的变量对象中寻找,也就是作用域链中当前执行上下文变量对象的的下一个变量对象,以此类推,依据作用域链依次寻找,直到作用域链的最末端——全局上下文变量对象。
(6)函数参数也被认为是当前函数上下文的变量,因此会被当前上下文的变量对象所包括。
var color = "blue";
function changeColor() {
let anotherColor = "red";
function swapColors() {
let tempColor = anotherColor;
anotherColor = color;
color = tempColor;
// 这里可以访问 color、anotherColor 和 tempColor
}
// 这里可以访问 color 和 anotherColor,但访问不到 tempColor
swapColors();
}
// 这里只能访问 color
changeColor();
3. 作用域链增强:在遇到 try-catch 结构 以及 with 语法时,会临时在作用域链前端添加一个上下文,对于 with 语句,会添加它指定的上下文,对于 catch 会创建一个新的变量对象,这个变量对象包含要抛出的错误对象的声明。