知识点:
* 执行上下文
* 每次函数执行的时候,会产生一个执行上下文,执行上下文是一个对象
* 执行上下文里面会创建一个变量对象 ,里面存放着当前函数内的变量
* 基本数据类型保存在变量对象里的,引用数据数据类型要单独在单堆内存里开辟空间保存。
* 变量对象里保存的就是堆里的内存地址
1 function task(m, n) {
2 var a = 1;
3 var b = {
4 name: '张三'
5 }
6 var c = [1, 2, 3];
7 }
8 task(10, 20);
我们可以知道task的执行上下文
1 let taskExecutionContext = {
2 this: window,
3 [[Scope]]: [函数的活动对象,全局的变量对象],
4 //Variable Object 变量对象 里面存的是当前函数执行要使用到的变量
5 VO: {
6 m: 10,
7 n: 20,
8 a: 1,
9 b: '内存地址指向对象{name: 张三}',
10 c: '内存地址指向数组[1,2,3]'
11 }
12 }
某个函数第一次被调用时,会创建一个执行环境(execution context)及相应的作用域链,并把作用域链赋值给一个特殊的内部属性(即 [[Scope]] )
当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。
执行环境(execution context,为简单起见,有时也称为“环境”)是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。
执行栈
知识点:
* 执行上下文栈
* 栈是一个数据,里面放着很多执行上下文
* 每次函数执行,都会产生一个执行上下文
* 全局上下文的VO,也被称为GO (Global Object) 全局对象
* 全局对象上的属性可以在任何地方被访问到
* 在浏览端GO就是VO就是window
function one() {
var a = 1;
var two = () => {
var b = 2;
var three = () => {
var c = 3;
debugger
console.log(a, b, c);
}
three();
}
two();
}
one();
执行上下文对象的VO栈
var executeContextStack = [];
//全局上下文
var globalExecuteContext = {
VO: { one: '()=>{}' }
}// 全局执行环境是最外层的执行环境
executeContextStack = [globalExecuteContext]
var oneExecuteContext = {
VO: { a: 1, two: '()=>{}' }
}// 执行到one把one推入环境栈中
executeContextStack = [oneExecuteContext, globalExecuteContext]
var twoExecuteContext = {
VO: { b: 2, three: '()=>{}' }
}// 执行到two把two推入环境栈中
executeContextStack = [, twoExecuteContext, oneExecuteContext, globalExecuteContext]
var threeExecuteContext = {
VO: { c: 3 }
}// 执行到three把three推入环境栈中
executeContextStack = [threeExecuteContext, twoExecuteContext, oneExecuteContext, globalExecuteContext]
作用域链的查找过程
function getVariableValue(varName) {
for (let i = 0; i < executeContextStack.length; i++) {
if (varName in executeContextStack[i].VO) {
return executeContextStack[i].VO[varName];
}
}
}
* 当执行one的时候,会创建一个执行上下文
* 编译阶段
* 创建VO
* 1. 处理参数,把参数放入VO
* 2. 扫描所有代码,找出function声明,从上往下依次执行 在编译阶段,会处理所有的函数声明,如果有重复的声明
* 后面会覆盖前面的声明
* 3.扫描var关键字 var是不赋值,只声明,值是undefined
* 4.在编译阶段不会处理let变量的,let的变量也不会放在VO里
* 编译完成
* 开始执行阶段
来源:https://www.cnblogs.com/wuxianqiang/p/12435076.html