深入理解js执行上下文
只有理解了执行上下文,才能更好地理解 JavaScript 语言本身,比如变量提升,作用域,闭包等
执行上下文
执行上下文是当前代码的执行环境。
执行上下文主要是三种类型:
- 全局执行上下文:全局执行环境是最外围的一个执行环境,在浏览器的全局对象是 window, this指向这个对象
- 函数执行上下文:可以有无数个,函数被调用的时候会被创建。每次调用函数都会创建一个新的执行上下文。
- eval执行上下文,很少用。
每个执行上下文,都有三个重要属性:
- 变量对象 (variable object, VO): 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。
- 作用域链(scope chain):当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。
- this
执行上下文的生命周期:创建 -> 执行 -> 回收
1. 创建阶段:
1.1 创建变量对象:
- 初始化函数的参数 arguments
- 函数声明
- 变量声明
举个简单的例子来理解变量对象
js">function getName(name) {var b = 2;
function foo() {};
var bar = function() {};
}
getName('lucystar')
此时的 AO 大致如下
AO = {arguments: {
0: 'lucystar',
length: 1
},
name: 'lucystar',
b: undefined,
foo: reference to function foo(){},
bar: undefined
}
1.2 创建作用域链
函数的作用域在函数定义的时候就确定了。作用域链本身包含变量对象,当查找变量时,会先从当前上下文中的变量对象中查找,如果没有找到,就会从父级执行上下文的变量对象中查找,一直找到全局执行上下文的变量对象
1.3 确定this的指向
这部分又分为多种情况,具体的可以查看另一篇文章 一文理解this&call&apply&bind
2. 执行阶段
执行变量赋值,代码执行
3. 回收阶段
执行上下文出栈被垃圾回收机制进行回收。关于内存回收的内容,可以查看 V8内存管理及垃圾回收机制
执行上下文栈
执行上下文栈是用来管理执行上下文的。在执行上下文创建好后,JavaScript引擎会将执行上下文压入到栈中,通常把这种用来管理执行上下文的栈称为执行上下文栈,又称调用栈。
let a = 'javascript';function foo() {
console.log('foo');
bar();
}
function bar() {
console.log('bar');
}
foo();
- 上述代码在浏览器加载时,JavaScript 引擎创建了一个全局执行上下文并把它压入到当前执行栈。
- 当遇到
foo()
函数调用时, JavaScript 引擎创建了一个 foo 函数执行上下文并把它压入到当前执行栈的顶部。 - 当从
foo()
函数内部调用bar()
函数时,JavaScript 引擎创建了一个 bar 函数执行上下文并把它压入到当前执行栈的顶部。 - 当函数 bar 执行完毕,它的执行上下文会从当前栈中弹出,控制流程到达下一个执行上下文,即
foo()
函数的执行上下文。 - 当 foo() 执行完成,它的执行上下文从栈弹出,控制流程到达全局执行上下文,一旦所有代码执行完成,javaScript 引擎就从当前栈中移除全局执行上下文。
参考
- JavaScript深入之执行上下文栈
- JavaScript深入之执行上下文
- JavaScript深入之变量对象
- 深入理解JavaScript系列(11):执行上下文(Execution Contexts)
- 《JavaScript高级程序设计 (第三版)》
以上是 深入理解js执行上下文 的全部内容, 来源链接: utcz.com/a/32361.html