1. 什么是执行上下文?
执行上下文就是当前JS代码被解析和执行时存在的环境(抽象概念)。
2. 执行上下文的类型
(1)全局执行上下文:这是默认的,最基础的执行上下文。
· 不在函数内部的代码都位于全局执行上下文中。
· 创建一个全局对象,其实就是我们的window对象。
· 将this指针指向这个全局对象。
(2)函数执行上下文:每次函数调用的时候,就会创建一个新的执行上下文。
· 每个函数都有自己的执行上下文。
· 一个程序中可以存在任意数量的函数执行上下文。
· 每一个函数执行上下文被创建,它都会按照特定的顺序执行一系列的步骤。
(3)eval函数执行上下文:运行在eval函数中的代码也获得了自己的执行上下文。
3. 执行上下文的生命周期
创建阶段 -- 执行阶段 -- 回收阶段
(1)创建阶段
当函数被调用,但是未执行内部的任何代码之前,会做以下几件事:
· 创建变量对象:初始化函数的参数arguments,提升函数声明和变量声明。
· 创建作用域链:在执行上下文创建阶段,在变量对象之后创建,作用域链本身包含变量对象。作用域链用来解析变量。
· 确定this指向。
(2)执行阶段
执行变量赋值、代码执行。
(3)回收阶段
执行上下文出栈,等待虚拟机回收。
4. 执行上下文栈
(1)在全局代码执行前,JS引擎就会创建一个栈来存储管理所有的执行上下文对象;
(2)在全局执行上下文(window)确定后,将其添加到栈中(入栈/压栈);
(3)在函数执行上下文创建后,将其添加到栈中(入栈/压栈);
(4)在函数执行完之后,将栈顶对象移除(出栈);
(5)当所有代码执行完后,栈中只剩下window;
5. 一些题
(1)var c = 1
function c(c) {
console.log(c)
}
c(2); // c is not a function
(2)if(!(b in window)){
var b = 1
}
console.log(b); // undefined
(3) function a() { } // 先执行变量提升,再执行函数提升
var a;
console.log( typeof a ) // function