对于对于Javascript 执行上下文的全面了解执行上下文的全面了解
在这篇文章中,将比较深入地阐述下执行上下文 – JavaScript中最基础也是最重要的一个概念。相信读完这篇文章后,你就会
明白javascript引擎内部在执行代码以前到底做了些什么,为什么某些函数以及变量在没有被声明以前就可以被使用,以及它
们的最终的值是怎样被定义的。
什么是执行上下文
Javascript中代码的运行环境分为以下三种:中代码的运行环境分为以下三种:
全局级别的代码全局级别的代码 – 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境。
函数级别的代码函数级别的代码 – 当执行一个函数时,运行函数体中的代码。
Eval的代码的代码 – 在Eval函数内运行的代码。
在网上可以找到很多阐述作用域的资源,为了使该文便于大家理解,我们可以将“执行上下文”看做当前代码的运行环境或者作
用域。下面我们来看一个示例,其中包括了全局以及函数级别的执行上下文:
上图中,一共用4个执行上下文。紫色的代表全局的上下文;绿色代表person函数内的上下文;蓝色以及橙色代表person函数
内的另外两个函数的上下文。注意,不管什么情况下,只存在一个全局的上下文,该上下文能被任何其它的上下文所访问到。
也就是说,我们可以在person的上下文中访问到全局上下文中的sayHello变量,当然在函数firstName或者lastName中同样可
以访问到该变量。
至于函数上下文的个数是没有任何限制的,每到调用执行一个函数时,引擎就会自动新建出一个函数上下文,换句话说,就是
新建一个局部作用域,可以在该局部作用域中声明私有变量等,在外部的上下文中是无法直接访问到该局部作用域内的元素
的。在上述例子的,内部的函数可以访问到外部上下文中的声明的变量,反之则行不通。那么,这到底是什么原因呢?引擎内
部是如何处理的呢?
执行上下文堆栈执行上下文堆栈
在浏览器中,javascript引擎的工作方式是单线程的。也就是说,某一时刻只有唯一的一个事件是被激活处理的,其它的事件
被放入队列中,等待被处理。下面的示例图描述了这样的一个堆栈: