由于JavaScript执行代码是一段一段地执行,并且会优先提取定义的函数式语句并执行在第二个例子中,第二次声明覆盖了第一次声明,所以都会输出foo2如果对其中一个进行变量提升,那么结果也会发生改变,这里不再赘述
变量对象全局上下文全局上下文中的全局变量指的就是全局对象在客户端JavaScript中,全局对象就是Windows对象
函数上下文在函数上下文中,用活动变量表示变量对象(AO)即在进入函数上下文后,变量对象才会变成活动对象
执行过程当进入执行上下文时,这时候还没有执行代码AO是进入函数上下文时被创建的,它通过函数的arguments进行初始化会包含函数的所有形参,变量声明,函数声明如遇到下面代码时
function foo(a) { var b = 2; function c() {} var d = function() {}; b = 3;}foo(1);
执行该函数上下文时,这时候的AO是
AO = { arguments: { 0: 1, length: 1 }, a: 1, b: undefined, c: reference to function c(){}, d: undefined}
代码执行阶段会顺序执行代码,执行完后是
AO = { arguments: { 0: 1, length: 1 }, a: 1, b: 3, c: reference to function c(){}, d: reference to FunctionExpression "d"}
总结
- 全局上下文的变量对象初始化是全局对象
- 函数上下文变量对象的初始化是argument对象
- 在进入函数上下文后添加形参,变量声明,函数声明的属性值
- 在执行代码阶段,会再次修改变量对象属性值
console.log(foo);function foo(){ console.log("foo");}var foo = 1;
结果为函数对象,因为在执行上下文时,首先会处理函数声明,然后才处理变量声明,如果之前已经有声明过的变量,则不会发生覆盖作用域链作用域链指的是由多个变量对象创建的链表当查找变量对象时,会优先从当前上下文的变量中查找,如果找不到,会到父级去找(词法作用域)
函数创建函数内部有一个属性scope,当函数被创建时,会保存所有的父级对象到其中scope可以表示所有父变量对象的层级链但是并不代表所有的作用域链
函数激活函数激活时,进入函数上下文,创建活动变量后,添加到作用域链的顶端接下来用一个例子来帮助理解
var scope = "global scope";function checkscope(){ var scope2 = 'local scope'; return scope2;}checkscope();
执行过程如下:- 函数被创建,保存作用域链到内部属性
checkscope.[[scope]] = [ globalContext.VO];
可见,此时作用域链内是全局对象2.函数执行上下文被压入上下文栈ECSstack = [Checkscope,globalContext]
3.函数并不立即执行,而是开始做准备工作,复制函数scope属性创建作用域链Scope:checkscope.[[scope]]用arguments创建活动对象,随后初始化活动对象AO = {arguments:{length:0;},scope2:undefined,Scope:checkscope.[[scope]]}
4.将活动对象压入作用域链顶端Scope:checkscope.[AO,[scope]]5.准备工作完成,开始执行函数,并且修改AO的值6.查找到scope2的值,函数返回后结束执行,并从ECS栈中弹出ECSstack = [globalContext]从ECMAScript规范解读thisECMAScript的中文版地址是(http://yanhaijing.com/es5/#115)ECMAScript有语言类型和规范类型两种类型语言类型就是开发者可以可以直接操作的,比如:undefined,null,string,number等等类型而规范类型是用算法描述ECMAScript语言结构和语言类型的接下来主要介绍规范类型中的Reference
Reference根据ECMAScript里所述,Reference是用来解释delete,typeof以及赋值等操作行为的尤大是这么说的
这里的 Reference 是一个 Specification Type,也就是 “只存在于规范里的抽象类型” 。它们是为了更好地描述语言的底层行为逻辑才存在的,但并不存在于实际的 js 代码中.Reference 有三个组成部分经验总结扩展阅读
- javascript编程单线程之异步模式Asynchronous
- javascript编程单线程之同步模式
- JavaScript函数式编程之函子
- GGD 论文解读《Rethinking and Scaling Up Graph Contrastive Learning: An Extremely Efficient Approach with Group Discrimination》
- 原生JavaScript
- Learning Records 计算机网络
- JavaScript之无题之让人烦躁的模块化
- GACL 谣言检测《Rumor Detection on Social Media with Graph Adversarial Contrastive Learning》
- Javascript 手写 LRU 算法