重学javascript之执行上下文栈

吐槽君 分类:javascript

前言

深入分析javascript之执行上下文栈

不忘初心,牢记使命

很多同学看到这里的时候可能会认为:“js基础太简单啦,有必要写吗?”。的确,相对于初学js的我们,现在回顾是很简单,但是自然界有一个规律的,也包括我们学习前端知识,那就是掌握真理,返璞归真,才能在走向升华的路上愈发坚实!

正文

什么是执行上下文栈

注意思考哦

  1. 如果我问你javascritp代码是顺序执行的吗?初学的很多同学都会一个直观的印象,那就是js代码是从上到下按顺序执行的。看一个例子:
//变量提升
var test = function() {
    console.log('test1');
}
test();

var test = function() {
    console.log('test2');
}
test();
 
//函数提升
function test() {
   console.log('test1');
}
test();

function test() {
   console.log('test2');
}

test();
 

结果都是两个 test2

javascript代码并不是一行一行的执行的,而是一段一段的分析执行的,也就是在执行一段代码的时候会进行一个准备工作,比如:变量提升、函数提升也就是创建执行上下文。

问: 这一段是怎么划分的呢,当我们的javascript引擎遇到怎样的一段代码才会做 准备工作呢?

可执行代码(一段)

全局代码、函数代码、eval代码。即遇到这样的一段代码的时候就会 创建执行上下文

执行上下文(execution context)

那么问题来了,这么多的可执行代码,这么多的一段一段,创建了这么多的执行上下文,那浏览器如何进行管理呢?接下来说一下执行上下文栈。

执行上下文栈(execution context)

可以通过数组去模拟一个执行上下文栈,来直观的说明。

ECStack = [];
 

当javascript开始要解释执行代码的时候,首先是全局代码,因此会向执行栈推入一个全局执行上下文,这里我们用globalContext表示。也就是说只有当整个应用程序结束的时候,执行栈ECStack才会被清空,函数执行完之前ECStack永远在执行栈中。

ECStack = [globalContext];

举一个嵌套调用的例子

function fun3() {
    console.log('fun3')
}
function fun2() {
    fun3();
}
function fun1() {
    fun2();
}
fun1();
 
ECStack = [globalContext]//push
ECStack = [globalContext, fun1]//push
ECStack = [globalContext, fun1, fun2]//push
ECStack = [globalContext, fun1, fun2, fun3] //push

ECStack = [globalContext, fun1, fun2, fun3] //pop
ECStack = [globalContext, fun1, fun2]//pop
ECStack = [globalContext, fun1]//pop
ECStack = [globalContext]//pop
 

思考题

实现上下文栈的应用场景

延续

记住: 每个执行上下文都有三个重要的属性:

  • 变量对象
  • 作用域链
  • this

回复

我来回复
  • 暂无回复内容