Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript 执行上下文和执行上下文栈(Execution Context Stack简称ECS) #58

Open
felix-cao opened this issue Sep 4, 2018 · 0 comments

Comments

@felix-cao
Copy link
Owner

felix-cao commented Sep 4, 2018

一、JavaScript 代码执行顺序

JavaScript 代码是从上到下顺序执行的,整个执行过程,分为两个阶段:

  • 编译阶段。将代码翻译成可执行代码,由编译器完成,作用域规则在这个阶段确定
  • 执行阶段。执行可执行代码,由引擎完成,执行上下文在这个阶段创建。

其中执行阶段具体流程如下:

  • 首先进入全局环境,创建一个全局执行上下文,在浏览器环境下全局变量对象 window,全局作用域Global,确定this指向,this==window

  • 在执行阶段,会完成变量赋值,函数引用,以及执行其他代码等。浏览器的断点调试只能用于执行阶段。

  • 在执行阶段,如果遇到函数引用,会进入函数环境,创建一个执行上下文。

而在这个执行上下文中,也分为创建阶段和执行阶段。接下来我们主要讨论函数环境的创建阶段和执行阶段,不考虑全局环境,因为全局环境也可以理解为在一个大的函数环境中。行为基本一致。

二、执行上下文

每当 Js 引擎转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。JavaScript 中的运行环境大概包括三种情况。

  • 全局环境:JavaScript 代码运行起来会首先进入该环境
  • 函数环境:当函数被调用执行时,会进入当前函数中执行代码
  • eval
     当代码在执行过程中,遇到以上三种情况,都会生成一个执行上下文,放入栈中,我们称其为函数调用栈(call stack)。栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文。处于栈顶的上下文执行完毕之后,就会自动出栈。

 注意:函数中,遇到 return 能直接终止可执行代码的执行,因此会直接将当前上下文弹出栈。

 执行上下文特点:

 - 单线程
 - 同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待
 - 全局上下文只有唯一的一个,它在浏览器关闭时出栈
 - 函数的执行上下文的个数没有限制
 - 每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此。

三、执行上下文的生命周期

在上面的描述中,我们可以看出一个执行上下文的生命周期通常包含三个发展阶段:创建阶段、代码执行阶段、执行完毕阶段。

  • 创建阶段:在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,以及确定this的指向.
  • 代码执行阶段:创建完成之后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其他代码。
  • 执行完毕阶段:执行完毕之后,就会开始将执行上下文出栈,随后释放掉所占用的内存

四、执行上下文栈(Execution Context Stack简称ECS)

引擎创建了执行上下文栈来管理执行上下文的顺序

栈stack是数据结构上的概念,用来处理数据的存放方式,特点为LIFO,即后进先出(Last in, first out)。

var a = 10;

function functionA() {

	console.log("Start function A");

	function functionB(){
		console.log("In function B");
	}

	functionB();

}

functionA();

console.log("GlobalContext");

  在浏览器中,javascript 引擎的工作方式是单线程的。也就是说,某一时刻只有唯一的一个事件是被激活处理的,其它的事件被放入队列中,等待被处理。下面的示例图描述了这样的一个堆栈:

  • javascript 代码文件被浏览器载入后,首先进入全局环境,创建一个全局执行上下文,全局变量对象 window,全局作用域 Global,确定 this 指向,this==window。当在全局上下文中调用执行一个函数时,程序流就进入该被调用函数内,此时引擎就会为该函数创建一个新的执行上下文,并且将其压入到执行上下文堆栈的顶部。浏览器总是执行当前在堆栈顶部的上下文,一旦执行完毕,该上下文就会从堆栈顶部被弹出,然后,进入其下的上下文执行代码。这样,堆栈中的上下文就会被依次执行并且弹出堆栈,直到回到全局的上下文。

Reference Doc

@felix-cao felix-cao changed the title JavaScript执行上下文栈(Execution Context Stack简称ECS) JavaScript 执行上下文和执行上下文栈(Execution Context Stack简称ECS) Sep 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant