JS进阶之---执行上下文,变量对象,变量提升
一、结构顺序大体介绍
JavaScript代码的整个执行过程,分为两个阶段,代码编译阶段与代码执行阶段。
编译阶段由编译器完成,将代码翻译成可执行代码,这个阶段作用域规则会确定。
执行阶段由引擎完成,主要任务是执行可执行代码,执行上下文在这个阶段创建。执行上下文也分为创建阶段和执行阶段。
1.首先进入全局环境,创建一个全局执行上下文,全局变量对象window,全局作用域Global,确定this指向,this==window。
2.在执行阶段,会完成变量赋值,函数引用,以及执行其他代码等。浏览器的断点调试只能用于执行阶段。
3.在执行阶段,如果遇到函数引用,会进入函数环境,创建一个执行上下文。而在这个执行上下文中,也分为创建阶段和执行阶段。接下来我们主要讨论函数环境的创建阶段和执行阶段,不考虑全局环境,因为全局环境也可以理解为在一个大的函数环境中。行为基本一致。
二、执行上下文
每次当Js引擎转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。JavaScript中的运行环境大概包括三种情况。
- 全局环境:JavaScript代码运行起来会首先进入该环境
- 函数环境:当函数被调用执行时,会进入当前函数中执行代码
- eval
当代码在执行过程中,遇到以上三种情况,都会生成一个执行上下文,放入栈中,我们称其为函数调用栈(call stack)。栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文。处于栈顶的上下文执行完毕之后,就会自动出栈。
注意:函数中,遇到return能直接终止可执行代码的执行,因此会直接将当前上下文弹出栈。
执行上下文特点:
• 单线程
• 同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待
• 全局上下文只有唯一的一个,它在浏览器关闭时出栈
• 函数的执行上下文的个数没有限制
• 每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此。
当调用一个函数时,一个新的执行上下文就会被创建。而一个执行上下文的生命周期可以分为两个阶段。
创建阶段
:在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,以及确定this的指向。
代码执行:阶段
创建完成之后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其他代码。

三、变量对象
在执行上下文的创建阶段,会进行变量对象的创建。
而变量对象的创建过程又分为:
1.参数对象创建。建立arguments对象,检查当前上下文中的参数,建立该对象下的属性与属性值。
2.函数声明。检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。
function声明会比var声明优先级更高一点。
3.变量声明。检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。
在执行上下文的执行阶段,进行变量对象的赋值,函数的引用等。
进入执行阶段之前,变量对象中的属性都不能访问!但是进入执行阶段之后,变量对象转变为了活动对象,里面的属性都能被访问了,然后开始进行执行阶段的操作。
变量对象和活动对象其实都是同一个对象,只是处于执行上下文的不同生命周期。
四、举个例子:
function test() {
var a = 1;
function foo() {
return 2;
}
}
test();
我们直接从test()的执行上下文开始理解。全局作用域中运行test()时,test()的执行上下文开始创建。为了便于理解,我们用如下的形式来表示。
创建阶段:
testEC = {
// 变量对象
VO: {},
scopeChain: {},
this: {}
}
// 因为本文暂时不详细解释作用域链和this,所以把变量对象专门提出来说明
// VO 为 Variable Object的缩写,即变量对象
VO = {
arguments: {...}, //参数对象。注:在浏览器的展示中,函数的参数可能并不是放在arguments对象中,这里为了方便理解,我做了这样的处理
foo: <foo reference> // 表示foo的地址引用
a: undefined
}
执行阶段:
VO -> AO // Active Object 即活动对象
AO = {
arguments: {...},
foo: <foo reference>,
a: 1
}
五、变量提升
变量提升是将变量声明提升到它所在作用域的最开始的部分。如:
console.log(a); //undefined
console.log(b); //Uncaught ReferenceError: b is not defined
var a = 1;
代码执行分为创建和执行两个阶段,代码开始执行的时候,创建阶段已经完成,所以变量对象已经创建完成。此时a是undefined,而b是没有的。
所以也就解释了变量提升的现象,因为在执行的时候,所有的变量对象早已创建完成,只是还没有被赋值。
JS进阶之---执行上下文,变量对象,变量提升的更多相关文章
- js执行上下文栈和变量对象
JavaScript执行上下文栈和变量对象 JS是单线程的语言,执行顺序肯定是顺序执行,但是JS 引擎并不是一行一行地分析和执行程序,而是一段一段地分析执行,会先进行编译阶段然后才是执行阶段. 例子一 ...
- 进阶学习js中的执行上下文
在js中的执行上下文,菜鸟入门基础 这篇文章中我们简单的讲解了js中的上下文,今天我们就更进一步的讲解js中的执行上下文. 1.当遇到变量名和函数名相同的问题. var a = 10; functio ...
- 【进阶1-2期】JavaScript深入之执行上下文栈和变量对象(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://mp.weixin.qq.com/s/hZIpnkKqdQgQnK1BcrH6Nw 阅读笔记 JS是单线程的语言,执行顺序肯定是顺 ...
- 关于javascript中的 执行上下文和对象变量
什么是执行上下文 当浏览器的解释器开始执行我们的js代码的时候,js代码运行所处的环境可以被认为是代码的执行上下文,执行上下文(简称-EC)是ECMA-262标准里的一个抽象概念,用于同可执行代码(e ...
- js中的执行上下文,菜鸟入门基础。
console.log(a); //Uncaught ReferenceError: a is not defined 因为没有定义a所以报错了. var a = 52; console.log(a) ...
- 通俗易懂的来讲讲js的函数执行上下文
0.开场白 在平时编写JavaScript代码时,我们并不会和执行上下文直接接触,但是想要彻底搞懂JavaScript函数的话,执行上下文是我们绕不过去的一个知识点. 1.执行上下文栈 JavaScr ...
- JS高阶---执行上下文栈
大纲: 主体: 注意:*******函数调用时才会产生上下文栈,声明时不会产生********** 顺序: 概念图: 执行上下文栈的顺序---→后进先出 其他概念图: 当前执行的上下文总是在顶部 全局 ...
- JS高阶---执行上下文
1.代码分类 2.全局执行上下文 3.函数执行上下文 .
- js中关于执行的顺序及变量存放方式的一点记录
Markdown在线编辑器 - www.MdEditor.com 1 首先关于数据类型,有基本数据类型,和引用数据类型 基本数据类型有:number,string,boolean等:引用数据类型一般指 ...
随机推荐
- [转]ionic工作原理
本文转自:https://segmentfault.com/a/1190000011495654 1.Ionic的工作原理 Ionic通过cordova把一个Web应用嵌入原生应用 用户打开一个ion ...
- WebFrom 小程序【条件查询】
实现按照各种条件对数据库进行综合查询 基本功能:可以根据用户需要灵活查询 重难点:各种条件的可能.限制. public List<users> selectA( string str,Ha ...
- 一款非常好用的万能本地离线激活工具,支持Office2016、Office2015、Win7、Win8/8.1/10、Win2008/2012/R2系统,全自动安装且无需联网状态即可全部激活,它由国外网友heldigard制作,小巧、简单,只需运行而不用去管它自动激活,能自动激活为180天无限循环,欢迎大家下载使用
office2016激活工具(KMS)是一款非常好用的万能本地离线激活工具,支持Office2016.Office2015.Win7.Win8/8.1/10.Win2008/2012/R2系统,全自动 ...
- 定义对象为什不可以写到while语句外面。VS2017
/// <summary> /// 绑定产品信息到网络列表 /// </summary> private void BindProduct() { Pros = new Lis ...
- hadoop 核心概念及入门
Hadoop Hadoop背景 什么是HADOOP HADOOP是apache旗下的一套开源软件平台HADOOP提供利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理,HADOOP的核 ...
- 具体CAS操作实现(无锁算法)
具体CAS操作 上一篇讲述了CAS机制,这篇讲解CAS具体操作. 什么是悲观锁.乐观锁?在java语言里,总有一些名词看语义跟本不明白是啥玩意儿,也就总有部分面试官拿着这样的词来忽悠面试者,以此来找优 ...
- NIO学习笔记四 :SocketChannel 和 ServerSocketChannel
Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道.可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的某台服务器. ...
- Python全栈学习_day002知识点
今日大纲: . while循环 . 格式化输出 . 运算符 . 编码初识 1. while循环 - while 无限循环: while True: # 死循环 print('大悲咒') print(' ...
- homebrew 安装 formula 的不同历史版本——以安装 node 为例
homebrew 安装 formula 的不同历史版本--以安装 node 为例 系统环境 macOS Mojave 10.14 Homebrew 1.8.0 Homebrew/homebrew-co ...
- wepy里面两种不同的写回调函数的方法
方案一const getHelpCenter = createAction(GET_HELP_CENTER, () => request('api/hisense/article/menu/li ...