javascript执行环境和栈

最近看到的一篇文章,讲到了javascript中基础但及其重要的一个概念:执行环境,并且用栈的理论描述

,非常深入,相信你看过之后能极好的理解javascript函数运行机制。也为javascript的作用域链等概念打

好基础。


在这篇文章中我将深入的分析javascript中最为基础的一个概念------执行环境,在读完该文章后,我希望

你能对执行环境有一个清晰和深入的认识,并且能够彻底明白一些问题:比如为什么变量和函数能够在

他们声明之前使用以及他们的值如何确定。

当一段代码执行的时候,明白他处于何种环境是非常有必要的,一般来说javascript代码分为三种:

  • 全局代码:这是默认的代码类型
  • 函数代码:进入一个函数体所执行的代码
  • eval代码:用eval执行的代码

看下面的一段代码



紫色代表全局上下文,绿色、蓝色和橙色代表3个不同的函数执行上下文。在一个程序中,全局上下文只有

一个,他是在代码执行前创建的,并且可以被其他上下文访问到,而函数执行上下文则有多个。

执行上下文栈的概念

一般来说,javascript的解释引擎在进行代码运行时是单线程的,也就是说在同一时间只会有一个任务在运行,

比如,在一个函数调用另一个函数时,调用者只有在被调用者执行完毕后才能再次执行,否则他是被挂起的。

其他待执行的任务就形成了一个队列,表现在javascript引擎中就是一个栈。栈很好的实现了这种机制。


我们知道,在代码首次被载入时,会创建一个全局上下文,当调用一个函数时,会创建一个函数执行

上下文,并把这个上下文环境置于栈的顶端,成为当前的活动栈。同理,如果该函数又调用了另外一个

函数,那么被调用的函数会形成一个新的执行上下文,并被推入栈顶。当该函数执行完毕返回后,会被

弹出该栈,从而使第二个执行环境代码得以执行。


(function foo(i) {
    if (i === 3) {
        return;
    }
    else {
        foo(++i);
    }
}(0));

该函数被调用了四次,那么相应的会形成四个执行环境。当条件满足时,函数停止执行,并按

顺序返回结果,最后全部被弹出该栈,仅剩一个全局上下文。

关于执行上下文,有5个关键点:

  • 单线程
  • 异步执行
  • 仅有一个全局上下文
  • 不限制函数上下文
  • 每次函数调用形成一个独立的执行环境,即使调用自身

执行环境结构详解

对于解释引擎来说,构造一个执行环境一般分为两个步骤:

创建阶段:当调用一个函数时,不会立即执行其中的代码,而会有一些准备工作

  • 创建变量,函数和参数
  • 构造作用域链
  • 设置this的值

执行阶段

对变量赋值,并执行函数代码

其实,我们可以认为一个执行环境是一个拥有3个属性的对象。

执行环境对象= {
    变量对象: { 参数、内部变量、函数声明 },
    作用域链: { 本函数变量对象+所有的父级变量对象},
    this值: {}
}



你可能感兴趣的:(javascript执行环境和栈)