JavaScript上下文对象详细解析,ES3与ES6
由于ES3与ES6全局上下文有区别,本文将会分别讲述ES3和ES6 各自的上下文对象
先讲的是ES3的, 需要注意的是ES3还不能使用let与const声明变量
一.JavaScript的上下文对象(Execution Context)
1.在JS代码执行前,会先对代码进行预解析,同时会生成一个上下文对象,也就是JS代码的执行环境
二.上下文对象类型
1.全局上下文对象,在代码载入浏览器时生成,在网页关闭后销毁
2.函数上下文对象,在函数调用时生成,在函数调用后销毁
3.Eval函数上下文
三.上下文对象的属性
Variable Object
VO对象是一个变量对象,当前作用域下的所有声明变量和函数声明都是VO对象的属性
VO对象在全局作用域下就是window
VO对象在函数作用域下叫做AO,我们不能访问到AO对象
[[scope]]
[[scope]]中所存储的是执行期上下文对象中VO(AO)的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链
任何执行上下文时刻的作用域, 都是由作用域链(scope chain)来实现(即函数内部的可访问范围是由scope chain来决定)
在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性(可能有些难以理解)
在函数访问变量时,会先在自身中找,如果没有找到会去scope chain 的VO(AO)列表中寻找,直到找到全局的VO对象(这也就是为什么内部函数中可以访问外部函数的变量)
this(不会细讲)
this主要由函数的调用方式决定
如果函数的形式调用的话this会指向window(因为全局函数是window对象的属性,也可以看做是window调用方法)
如果以方法的形式调用的话this指向调用该方法的对象
特殊的箭头函数没有this,其this指向上一层作用域的this
四.详解全局上下文和函数上下文
执行环境栈:
什么是执行环境栈: 执行环境栈是代码执行期间用来管理所有上下文对象的数据结构,它是一个后进
先出的栈
执行环境栈执行流程:当进入页面时,代码预解析后,会创建一个全局上下文对象并压入栈中,然后执行
代码,之后每当碰到函数调用时,都会生成一个函数上下文并压入栈中
var num = 10;function fun() {var num2 = 20;console.log(num2); }fun();下面是该段代码的执行环境栈工作流程图
本段JS代码在执行前,会先 生成一个上下文对象,并且生成VO对象与确定this(window)的指向,全局上下文中没有[[scope]]属性,在生成上下文对象后,会将其压入到执行环境栈中,此时会有一个指针running指向该上下文,表示当前正在执行的代码是该环境中的,在代码执行到fun()时,会生成一个函数上下文并入栈,并且指针running会指向函数上下文
注意:全局上下文中的VO会将num和fun都当成它的属性,函数上下文中的AO会将num2当做它的属性
当fun函数执行完成后funExectionContext就会被弹出栈,此时函数上下文中的this、scope、AO都会被销毁,并且running指针会重新指向全局上下文,当页面关闭后,全局上下文弹出栈
2.执行上下文的创建:
创建上下文主要就是创建它的三个属性VO/AO、this、scope
VO/AO:会将当前环境下所有的变量和函数都当做VO/AO的属性,AO中还会有形参与arguments
this:根据不同的调用规则,this的指向不同
scope:一个函数的作用域链生成分为定义时,与调用时
1.作用域链的生成
function fn(){}fn();//当fn函数执行完成后,fn函数的上下文对象会出栈,并且作用域链、AO、this会销毁注意://如果fn内部还嵌套了一个函数,该函数的作用域链中保存着fn函数AO的链接,那么//此时fn函数的AO就不会销毁了(因为AO对象还在被引用),这就形成了闭包,闭包简单来说//就是一个函数内部可以访问另一个函数内部的变量(通过作用域链进行访问),也可以说一个//函数调用完成后,因为它的AO对象仍然在被引用,所以该函数的作用域没有被销毁 //这儿只是简单说了一下闭包,不理解也没有关系,博主后期会更新闭包的相关知识
fn函数定义时:
fn函数调用时,生成VO对象,并且会把fn的AO对象放到作用域链的最顶端
2.上下文生成的代码演示
console.log(100);var a = 10;function fun(x) {var b = 20;console.log(b);}fun(20);//全局上下文对象 GlobalExecutionContext: {VO:{a:undefined, //使用var声明的变量会先赋值为undefinedfun:fun函数的地址},this:window,}//函数上下文:funExectionContext: {AO:{arguments:{x:20,length:1},b:undefined, //使用var声明的变量会先赋值为undefinedx:20,//形参在AO对象生成时,就已经赋值},this:window,scope:{ //在函数中寻找变量,会先在自身中,如果没有找到,就会去scope中的//父级VO/AO找,直到全局的VOAO(fun)VO(window)}}
需要注意的是在全局上下文VO对象生成后,会把所有的全局内置方法(alert、isNaN)与变量(Infinity)都当成它的属性,比如console对象,所以在函数内部才可以通过作用域链访问到console对象
在上面的代码中会生成4个执行上下文,console.log也会生成,因为它是一个内置函数,所有博主就没有写
3.函数上下文AO对象属性的优先级:
函数> 形参 > 声明变量
function test(a) {function a() {};var a;console.log(a);//发现是函数}test(10)//此时变量 a 的值是什么?testExecutionContext:{AO:{a:a函数的地址值, //其实在AO寻找函数与声明变量和形参时,发现有同名时a:10, //会忽略声明变量和形参,同理当变量和形参同名时,会忽略变量 a:undefined,}}
后续会继续更新ES6的上下文对象,ES6和ES3的概念基本相同,只是用的术语不同,如果想要提前了解,可以看参考下的ES6上下文对象详解
参考:
作用域链
JavaScript的执行环境
ES6上下文对象详解
JavaScript上下文对象详细解析,ES3与ES6相关推荐
- referer详细解析
javascript操作referer详细解析 来源:A5技术交流 作者:shk 时间:2015-02-06收藏本页 referrer地重要性 http请求中有一个referer地报文头,用来指明当前 ...
- 【JavaScript】JavaScript Date 对象常用方法大全,例如:getDate、getDay、getFullYear、getHours等(包括作用、语法、参数解析、详细用例)
JavaScript Date常用方法 1.getDate() 方法 2.getDay() 方法 3.getFullYear() 方法 4.getHours() 方法 5.getMillisecond ...
- JavaScript保姆级教程 ——— 重难点详细解析(万字长文,建议收藏)
JavaScript保姆级教程 --- 重难点详细解析(建议收藏) 1. JS函数 2. JS事件 3. JavaScript 对象 4. JavaScript prototype(原型对象) 5. ...
- 前端头像上传功能实现之普通图片/头像上传 详细解析1【扩展知识FormData对象】
上传的图片/头像有两种方案上传 第一种我们不对图片做处理直接上传到服务器端,把图片上传到服务器的img文件夹当中,然后我们把图片的地址信息存储在数据库当中,用图片的时候我们直接调用地址 第二种方案是我 ...
- Ajax中XMLHttpRequest对象的详细解析
| responseXML | 服务器的相应,表示为XML,这个对象可以解析为一个DOM | | status | 服务器的HTTP状态码 | | statusText | HTTP状态的对应文本 | ...
- CANopen伺服控制-服务数据对象(SDO)详细解析
CANopen服务数据对象(SDO)详细解析 SDO"服务数据对象"允许对对象字典进行读或写访问.数据服务对象,以下简称SDO 在下文中,对象字典的所有者称为"服务器/主 ...
- 详细解析 JavaScript 获取元素的坐标
随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) from:https://www.cnblogs.com/dong-xu/p/7150715.html?utm ...
- java 类型检查_Java开发对象类型检查详细解析
原标题:Java开发对象类型检查详细解析 前面介绍了类的多态性,来自于鸡类的实例chicken,既能用来表达公鸡实例,也能用来表达母鸡实例.可是这导致了一个问题,假如在call方法内部需要手工判断输入 ...
- 混淆概念详细解析:Python中类、对象、方法、函数和属性的区别和理解
混淆概念详细解析:Python中类.对象.方法.函数和属性的区别和理解 前言 一.类.对象.方法.函数和属性的区别和理解 二.一个类的简单案例和对各种概念的理解 三.总结 欢迎学习交流! 邮箱: z- ...
最新文章
- vmware响应时间过长_性能调优高并发下如何缩短响应时间
- 汇总同一时间段的数据_数据集干货:一文读懂Mapsidejoin
- 从零到一编码实现Redis分布式锁
- OSSIM系统的安装教程(超详细)
- 亚洲诚信带你玩转[2018国家网络安全宣传周]上海地区活动!
- 允许自行设计赛道之后,参赛同学都想到了什么呢?
- 如何更好的排版介绍性文字
- 13行代码AC_Justifying the Conjecture Gym - 102394J(解题报告)
- 系统学习 TypeScript(二)——开发流程和语法规则
- vcpkg如何全面卸载和重新安装包
- Matlab2019 中文显示问题(乱码与方框)
- for循环中控制事务单个提交问题
- 从微信小程序到QQ小程序:云开发CloudBase的一云多端实践
- Mairadb数据库基本操作之数据管理
- Jmeter模拟上传图片
- English语法_to不定式
- 由蓝眼睛岛问题引发的思考
- java/php/net/python中医体质的社区居民健康管理设计
- 电脑显示服务器意外终止,Win7提示Dcom Server Process Launcher服务意外终止怎么办?...
- linux c语言反汇编分析,通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作...
热门文章
- lambda表达式 拉姆达
- ping请求超时问题研究
- 可以正常上网但ping 127.0.0.1或localhost出现请求超时的解决方法
- C++异常之栈解旋(unwinding)
- Postman使用小技巧 - 用Postman生成Request代码
- POJ 1417 True Liars(带权并查集+DP)
- JavaWeb25.3【综合案例:注册功能(含邮箱激活账号)】
- EOS智能合约开发系列(七): 多索引table
- 字节跳动宣布再次回购期权,我大腿拍断,遗憾错失最少2个亿现金!选择真的大于努力!...
- 记录一次清理挖矿程序