前言
执行环境(execution context)也有翻译为执行上下文,这是JS中非常基础但是也非常重要的一个概念,通过理解执行环境我们可以更加了解js的运作机制。这篇文章就来简单理解一下什么是执行环境,以及它究竟是怎么样运作的。
什么是执行环境
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。这是高级编程中的一句话。
说简单点理解,执行环境其实就是一个环境,在这个环境中保存了一些重要的数据。
每个函数都有自己的执行环境,此外还存在一个全局的执行环境,在web浏览器中,该执行环境被认为是window对象(因为所有的属性和方法都是window对象创建的)。
当执行环境中的所有代码执行完毕后,该执行环境就会被销毁,退出执行栈。(全局执行环境直到浏览器关闭才会被销毁)
执行环境与执行栈
要理解执行环境我们还需要了解一个概念:执行栈。我们都知道栈是一种LIFO(Last-In-First-Out)的数据结构,也就是后进先出。
通过我前面的关于js事件循环机制的文章现在我们可以知道,当js执行到非异步的函数的时候会立马将该函数推入到执行栈中,那么现在我们可以知道被推入执行栈的是该函数的执行环境,当函数执行完毕就会被弹出,也就是执行环境被销毁,然后根据执行流继续执行后面的代码。
到这里我相信执行环境的基本概念已经有了,也就是在执行某一函数时的环境,当函数执行完毕该环境就会被销毁。
现在我们可以通过一个例子来更加形象的理解执行栈与执行环境:1
2
3
4
5
6
7
8
9function foo() {
console.log('csznb');
function bar() {
console.log('cszsfyq');
}
}
function baz() {
console.log('cszfcs');
}
我们可以通过图片方便理解:
通过图片我们就可以很直观的理解执行栈与执行环境了。
在开始执行foo函数之前,执行栈中就只有全局的执行环境,
当执行到foo函数就会把其执行环境推入执行栈中执行其中的代码,
当执行到bar函数则把bar函数的执行环境推入到执行栈中,由于此时这两个函数都还没有执行完毕,所以这两个函数的执行环境都存在于执行栈中,
当执行完bar函数中的代码,bar函数的执行环境就被弹出,foo函数的代码也意味着执行完毕,执行环境也被弹出,
接着开始执行baz函数,将其执行环境推入执行栈中,当执行完函数中的代码则被弹出,
最后只剩下一个全局执行环境,当浏览器关闭,全局执行环境也被销毁。
执行环境中的内容
前面也提到了执行环境其实就是一个环境,其中保存了重要的数据,那么究竟保存的是什么数据呢?
首先执行环境中很重要的一部分就是变量对象,变量对象将包含当前函数中的许多重要信息。
执行环境中还保存了作用域链,当代码在一个环境中执行时,会创建变量对象的一个作用域链。
另外在执行环境中还确定了this的指向。
关于这三者的详细理解这里我就不介绍了,后面会些专门的文章来解释。
总结
当执行到一个函数,该函数的执行环境就会被推入执行栈,当这个函数完全执行完毕执行环境就会被弹出执行栈。全局执行环境一开始就存在与执行栈之中,只有当浏览器关闭才会被销毁。
这里只介绍了一些关于执行环境基本的知识,后面还会有更加详细的关于变量对象以及作用域链的理解。