美文网首页
js执行上下文

js执行上下文

作者: 青色琉璃 | 来源:发表于2020-04-14 16:08 被阅读0次

    执行上下文(Execution Context):函数执行前进行的准备工作(也称执行上下文环境)。

    当执行代码进入一个环境时,就会为该环境创建一个执行上下文,它会做一些准备工作,如变量提升,确定作用域等。


    一,执行上下文的类型

    js中有三种执行上下文类型:

    全局执行上下文:顶层上下文,任何不在函数内部的代码都在其中。上下文中的大哥大!它干了两件事:1.创建一个全局的window对象(浏览器环境下),2.设置this的值等于这个全局对象。(一个程序中只会有一个全局执行上下文)

    函数执行上下文:函数被调用时,会创建新的上下文,可以有多个。

    Eval函数执行上下文:aval函数专用,用的不多,没排面,不讨论。

    执行栈

    在js中,通过栈的存取方式来管理执行上下文,我们可称其为执行栈,或函数调用栈(Call Stack)。

    image

    栈遵循“先进先出,后进后出”的规则,也就是LIFO(Last In First Out)规则,可以用乒乓球盒子来类比理解。

    特点:

    1,先进先出,后进后出

    2,出口在顶部,且仅有一个

    当js引擎第一次遇到你的脚本时,它会创建一个全局的执行上下文并且压入当前执行栈。而每当引擎遇到一个函数调用,它会为该函数创建一个新的执行上下文并压入栈的顶部。

    引擎会执行那些位于执行上下文顶栈顶的函数,当函数执行结束时,其执行上下文从栈中弹出,控制流程达到当前栈中的下一个上下文。

    我们可以通过示例代码来理解:

    
    function foo () {
    
       function bar () {
    
           return 'I am bar';
    
       }
    
       return bar();
    
    }
    
    foo();
    
    image

    二,执行上下文的生命周期

    执行上下文的生命周期有两个阶段:

    创建阶段(进入执行上下文,如:变量提升等)

    执行阶段

    创建阶段的操作:

    1,创建变量对象

    函数环境会初始化创建Arguments对象(并赋值),并传递长度length

    匿名函数声明(并赋值)

    1,变量声明,函数表达式声明(未赋值,即变量提升)

    2,确定this指向(this由调用者确定)

    3,确定作用域(词法环境确定,哪里声明,哪里确定)

    执行阶段的操作

    1,变量对象赋值

    变量赋值

    函数表达式赋值

    2,调用函数

    3,执行其他代码片段

    值得注意的是,执行上下文可存在多个,因此在递归中可能因为没有终止条件而造成死循环,堆栈溢出错误。

    // 递归调用自身

    function foo() {
    
     foo();
    
    }
    
    foo();
    
    // 报错: Uncaught RangeError: Maximum call stack size exceeded
    

    文末总结:

    1,js是单线程

    2,栈顶的执行上下文处于执行中时,其他的需要排队

    3,处于底部的总是全局上下文,关闭页面时出栈

    4,函数执行上下文可存在多个,但应避免递归时堆栈溢出

    5,函数调用时就会创建新的上下文,即使调用自身,同样如此

    参考文档:

    https://mp.weixin.qq.com/s/lAvyjfBZvX0E50QiW3aW7w

    https://juejin.im/post/5ba32171f265da0ab719a6d7(并未讨论其中的词法环境)

    相关文章

      网友评论

          本文标题:js执行上下文

          本文链接:https://www.haomeiwen.com/subject/ipjtvhtx.html