zoukankan      html  css  js  c++  java
  • 深入js——执行上下文栈

    前言

    js的很多不太好理解的概念,比如作用域、this、闭包,可以说都与执行上下文有关,弄懂了执行上下文,再去理解这些概念就没有难度了。

    可执行代码

    但js每执行一段可执行代码,就会进入一个执行上下文;js的可执行代码有3种:

    • 全局代码
    • 函数代码
    • eval代码
      因此,js对应有3种执行上下文:全局上下文、函数上下文、eval上下文。

    执行上下文栈

    当js执行一段代码时,可能出现很多执行上下文,那如何管理这些上下文呢?答案是通过栈来管理,把这种用来管理执行上下文的栈称为执行上下文栈,又称调用栈
    每进入一个执行上下文,js就会向栈中push当前上下文,每退出一个执行上下文就会pop当前此上下文。因此堆栈底部永远都是全局上下文(global context),而顶部就是当前(活动的)执行上下文。

    通过浏览器控制台查看调用栈

    • 查看Call Stack
      打开控制台,在“Source”标签下打断点,可以在右边的Call Stack中查看到调用栈的当前状态以及变化。
      调用栈
      从上图可以看出,当执行到foo函数时,调用栈中从上到下有3个执行上下问,分别为当前上下文foo,bar上下文和全局上下文(anonymous译匿名者)。

    可以通过在不同执行上下文打断点,观察Call Stack变化,可以更好的理解执行上下文栈。

    • 打印调用栈
      console.trace可以打印出调用栈的信息。
      在foo函数内部执行console.trace(),可以打印出调用栈的当前状态。
      console.trace()

    思考题

    var scope = "global scope";
    function checkscope(){
        var scope = "local scope";
        function f(){
            return scope;
        }
        return f();
    }
    checkscope();
    
    var scope = "global scope";
    function checkscope(){
        var scope = "local scope";
        function f(){
            return scope;
        }
        return f;
    }
    checkscope()();
    

    以上2段代码的执行结果一样,但它们的调用栈变化却不一样。可以先自己分析下,然后再通过Call Stack检验下看对不对。下面做简要分析:
    第一段代码,调用栈的变化过程:

    Stack.push(<anonymous>)
    Stack.push(<checkscope>);
    Stack.push(<f>);
    Stack.pop(); // <f>
    Stack.pop(); // <checkscope>
    Stack.pop(); // <anonymous>
    

    第二段代码,调用栈的变化过程:

    Stack.push(<anonymous>)
    Stack.push(<checkscope>);
    Stack.pop(); // <checkscope>
    Stack.push(<f>);
    Stack.pop(); // <f>
    Stack.pop(); // <anonymous>
    

    小结

    通过Call Stack可以很清楚看出调用栈的变化,多试多观察栈的变化,对调用栈就会很清楚啦。
    本文可以算是从宏观上讲了执行上下栈的变化,那执行上下文里面是怎样的呢?又是怎样变化的呢?
    接下来讲讲与执行上下文相关的变量对象、作用域链和this。

    参考:
    冴羽深入js系列
    汤姆大叔深入js系列
    极客时间——浏览器工作原理与实践课程

  • 相关阅读:
    异常
    gateway 网关
    Hystrix 图形化界面
    Hystrix 服务限流
    linux-CenOS修复内核或修改内核系统启动顺序
    Linux-CentOS不能yum update/upgrade.除非是初始环境
    Linux-CentOS配置网卡
    安装SQLSERVER2008提示错误SQL100MSI
    金蝶采购标志
    Pycharm社区版安装外部库文件
  • 原文地址:https://www.cnblogs.com/youhong/p/12204739.html
Copyright © 2011-2022 走看看