摘要:思考题在深入学习之词法作用域和动态作用域中,提出这样一道思考题思考题一思考题二两段代码都会打印但是还是有些许差异的,本文就详细的解析执行上下文栈和执行上下文的具体变化过程。
在《深入学习js之——执行上下文栈》中说过,当JavaScript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)
对于每一个执行上下文,都有三个重要的属性:
变量对象(Variable object VO)
作用域链(Scope chain)
this
本文我们结合着这三个部分的内容,讲讲执行上下文的具体处理过程。
思考题在《深入学习js之——词法作用域和动态作用域》中,提出这样一道思考题:
// 思考题一: var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f(); } checkscope(); // 思考题二: var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f; } checkscope()();
两段代码都会打印local scope,但是还是有些许差异的,本文就详细的解析执行上下文栈和执行上下文的具体变化过程。
具体分析我们分析第一段代码:
var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f(); } checkscope();
执行过程如下:
1、执行全局代码,创建全局执行上下文,全局上下文被压入执行上下文栈
ECStack = [ globalContext ];
2、全局上下文初始化
globalContext = { VO: [global], Scope: [globalContext.VO], this: globalContext.VO }
2、初始化的同时,checkscope 函数被创建,保存作用域链到函数内部的属性[[scope]]
checkscope.[[scope]] = [ globalContext.VO ];
3、执行checkScope 函数,创建checkScope 函数执行上下文,checkScope 函数执行上下文被压入执行上下文栈:
ECStack = [ checkscopeContext, globalContext ];
4、checkscope 函数执行上下文初始化:
1.复制函数 [[scope]] 属性创建作用域链,
2.用 arguments 创建活动对象,
3.初始化活动对象,即加入形参、函数声明、变量声明,
4.将活动对象压入 checkscope 作用域链顶端,
同时 f 函数被创建,保存作用域链到 f 函数的内部属性[[scope]]
checkscopeContext = { AO: { arguments: { length: 0 }, scope: undefined, f: reference to function f(){} }, Scope: [AO, globalContext.VO], this: undefined }
5、执行f函数,创建 f 函数执行上下文,f 函数执行上下文被压入执行上下文栈
ECStack = [ fContext, checkscopeContext, globalContext ]
6、f 函数执行上下文初始化, 以下跟第 4 步相同:
1.复制函数 [[scope]] 属性创建作用域链
2.用 arguments 创建活动对象
3.初始化活动对象,即加入形参、函数声明、变量声明
4.将活动对象压入 f 作用域链顶端
fContext = { AO: { arguments: { length: 0 } }, Scope: [AO, checkscopeContext.AO, globalContext.VO], this: undefined }
7、f 函数执行,沿着作用域链查找 scope 值,返回 scope 值
8、f 函数执行完毕,f 函数上下文从执行上下文栈中弹出
ECStack = [ checkscopeContext, globalContext ]
9、checkscope 函数执行完毕,checkscope 执行上下文从执行上下文栈中弹出
ECStack = [ globalContext ]
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/102558.html
摘要:开篇作用域是每种计算机语言最重要的基础之一,因此要想深入的学习作用域和作用域链就是个绕不开的话题。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。这时候执行上下文的作用域链,我们命名为至此,作用域链创建完毕。 开篇 作用域是每种计算机语言最重要的基础之一,因此要想深入的学习JavaScript,作用域和作用域链就是个绕不开的话题。 在《深入学习js之—-执行上下文栈》中我们提到...
摘要:当遇到函数调用时,引擎为该函数创建一个新的执行上下文并把它压入当前执行栈的顶部。参考链接理解中的执行上下文和执行栈深入之执行上下文栈 开篇 作为一个JavaScript的程序开发者,如果被问到JavaScript代码的执行顺序,你脑海中是不是有一个直观的印象 -- JavaScript 是顺序执行的,可事实真的是这样的吗? 让我们首先看两个小例子: var foo = functio...
摘要:写在前面深入系列共计篇已经正式完结,这是一个旨在帮助大家,其实也是帮助自己捋顺底层知识的系列。深入系列自月日发布第一篇文章,到月日发布最后一篇,感谢各位朋友的收藏点赞,鼓励指正。 写在前面 JavaScript 深入系列共计 15 篇已经正式完结,这是一个旨在帮助大家,其实也是帮助自己捋顺 JavaScript 底层知识的系列。重点讲解了如原型、作用域、执行上下文、变量对象、this、...
摘要:在中的应用采用词法作用域,也就是静态作用域。那什么又是词法作用域或者静态作用域呢请继续往下看静态作用域与动态作用域因为采用的是词法作用域函数的作用域在函数定义的时候就决定了。 开篇 当我们在开始学习任何一门语言的时候,都会接触到变量的概念,变量的出现其实是为了解决一个问题,为的是存储某些值,进而,存储某些值的目的是为了在之后对这个值进行访问或者修改,正是这种存储和访问变量的能力将状态给...
摘要:模块化是随着前端技术的发展,前端代码爆炸式增长后,工程化所采取的必然措施。目前模块化的思想分为和。特别指出,事件不等同于异步,回调也不等同于异步。将会讨论安全的类型检测惰性载入函数冻结对象定时器等话题。 Vue.js 前后端同构方案之准备篇——代码优化 目前 Vue.js 的火爆不亚于当初的 React,本人对写代码有洁癖,代码也是艺术。此篇是准备篇,工欲善其事,必先利其器。我们先在代...
阅读 3369·2023-04-26 01:46
阅读 2854·2023-04-25 20:55
阅读 5322·2021-09-22 14:57
阅读 2947·2021-08-27 16:23
阅读 1692·2019-08-30 14:02
阅读 2042·2019-08-26 13:44
阅读 605·2019-08-26 12:08
阅读 2930·2019-08-26 11:47