执行上下文
执行上下文栈的作用:
是用来跟踪代码的,由于JS是单线程的,每次只能做一件事情,其他的事情会放在指定的上下文栈中排队等待执行。
经过阅读下面这几个博客终于理解了函数上下文的意思。
慕课网 带图片的解释 https://zhuanlan.zhihu.com/p/72959191 初步理解
冴羽 https://github.com/mqyqingfeng/Blog/issues/5
加深理解 https://blog.youkuaiyun.com/yucihent/article/details/79768210
总结:
VO/AO:
VO(变量对象)
创建执行上下文时与之关联的会有一个变量对象,该上下文中的所有变量和函数全都保存在这个对象中。
AO(活动对象)
进入到一个执行上下文时,此执行上下文中的变量和函数都可以被访问到,可以理解为被激活。
创建阶段:创建阶段分为函数和变量
函数:
-
每扫描到一个函数什么就会在VO里面用函数名创建一个属性,为一个指针,指向该函数在内存中的地址
-
如果函数名在VO中已经存在,对应的属性值会被新的引用覆盖
变量:
-
每扫描到一个变量就会用变量名作为属性名,其值初始化为undefined
-
如果该变量名在VO中已经存在,则直接跳过继续扫描
函数声明,会替换已有变量对象
变量声明,不会替换形参和函数
执行阶段:
- 执行函数体中的代码,给VO中的变量赋值
// var a=10
// console.log(this);
// console.log(this.window);
// console.log(this.a);
//这些属性都需要再浏览器的控制台中使用,再node的运行时中是没有用的。
// 1.函数的所有形参 (如果是函数上下文)
// 由名称和对应值组成的一个变量对象的属性被创建
// 没有实参,属性值设为 undefined
// 2.函数声明
// 由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建
// 如果变量对象已经存在相同名称的属性,则完全替换这个属性
//这里就是函数提升的内部实现
// 3.变量声明
// 由名称和对应值(undefined)组成一个变量对象的属性被创建;
// 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性
// function foo(a) {
// var b = 2;
// function c() {}
// var d = function() {};
// b = 3;
// }
// foo(1);
// 在进入执行上下文后,这时候的 AO 是:
// AO = {
// arguments: {
// 0: 1, //这里的1,我的理解是传入的参数
// length: 1 // 这里的1,我的理解是形参的个数,或者说形参的长度
// },
// a: 1, //这里的1是传入的a值
// b: undefined, //这里的unddefined 是变量所有是undefined 被使用的时候才会被赋予值
// c: reference to function c(){},//这里的值是引用函数
// d: undefined //这里的unddefined 是变量所有是undefined 被使用的时候才会被赋予值
// }
//这是因为在进入执行上下文时,首先会处理函数声明,其次会处理变量声明,如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。
// base: EnvironmentRecord, 所在的位置 所在位置处在全局位置,就是全局作用域 处在函数内部就是函数本身
// name: 'foo', 名字
// strict: false 是否是严格模式