阅读 78

javaScript上下文

JS代码在执行前,JS引擎总要做一番准备工作,这份工作其实就是创建对应的执行上下文;

执行上下文有且只有三类,全局执行上下文,函数上下文,与eval上下文;由于eval一般不会使用

上下文的方式

全局执行上下文(只有一个,由浏览器创建,能够使用this访问它) 我们通过var创建的全局对象,都可以通过window直接访问

函数执行上下文(能有无数个,每当函数被调用时都会创建,同一个函数被调用依然创建)

eval

上下文的栈

调用栈: LIFO(Last In First Out后进先出,也就是先进后出)
栈底永远有一个全局执行上下文(window)
只有栈顶的上下文在执行,其余在等待,每当有函数被调用都会创建一个上下文

  • 单线程
  • 同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待
  • 全局上下文只有唯一的一个,它在浏览器关闭时出栈
  • 函数的执行上下文的个数没有限制
  • 每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此
function f1() {
    f2();
    console.log(1);
};
function f2() {
    f3();
    console.log(2);
};
function f3() {
    console.log(3);
};

f1();//3 2 1
复制代码

创建阶段跟执行阶段

创建阶段

ExecutionContext = {  
    // 确定this的值
    ThisBinding = <this value>,
    // 创建词法环境组件
    LexicalEnvironment = {},
    // 创建变量环境组件
    VariableEnvironment = {},
};
复制代码

绑定this
创建词法环境: 存储函数声明与let const声明的变量, 包括环境记录与外部环境引入记录
创建变量环境: 仅仅存储var声明的变量包括环境记录与外部环境引入记录
在执行上下文创建阶段,函数声明与var声明的变量在创建阶段已经被赋予了一个值,var声明被设置为了undefined,函数被设置为了自身函数,而let const被设置为未初始化。这就是为什么var跟函数有变量提升,而let,const没有的原因

执行阶段

代码执行时根据之前的环境记录对应赋值,比如早期var在创建阶段为undefined,如果有值就对应赋值,像let const值为未初始化,如果有值就赋值,无值则赋予undefined。

更多参考

文章分类
前端
文章标签