javascript预编译的过程
预编译的两种情况
全局:
1.全局 直接是script标签中的代码,不包括函数执行
执行前:
1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析
2.分析变量声明,变量名为属性名,值为undefined
3.分析函数声明,函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖
函数内部(局部):
1. 函数调用,也是会生成自己的作用域(AO:active object),AO活动对象. 函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO
a. 函数执行前的一瞬间,生成AO活动对象
b. 分析参数,形参作为对象的属性名,实参作为对象的属性值
c. 分析变量声明,变量名为属性名,值为undefined,如果遇到AO对象上属性同名,不去做任何改变
d. 1.4 分析<b>函数声明</b>,函数名为属性名,值为函数体,如果遇到AO对象上属性同名,则无情覆盖
2. 逐行执行。
代码分析如下:
<script type="text/javascript">
console.log(a);
console.log(b)
var a = 100;
console.log(a)
var b = 200
var c = 300
function a(){
}
function fun(){
}
console.log(a);
</script>
全局 直接是script标签中的代码,不包括函数执行
执行前:
1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析
GO = {
自带的属性都不写
}
2.分析变量声明,变量名为属性名,值为undefined
GO = {
a : undefined,
b : undefined,
c : undefined
}
3.分析<b>函数声明</b>,函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖
GO = {
a : function a(){},
b : undefined,
c : undefined,
fun : function fun(){}
}
此时,GO就是预编译完成的最终对象,词法分析结束
4.逐行执行,分析过(变量声明,函数声明)不用管了,只管赋值(变量赋值)
11行的时候,a赋了一次值,值改变为100
GO = {
a : 100,
b : undefined,
c : undefined,
fun : function fun(){}
}
局部
<script type="text/javascript">
var num = 100;
function fun(num){
console.log(num)
}
fun(5)
fun(10)
</script>
1.预编译的时候
GO = {
num : undefined,
fun : function
}
2.执行过程
走到9行
GO = {
num : 100,
fun : function
}
走到14行,函数的调用
3.函数调用,也是会生成自己的作用域(AO:active object),AO活动对象. 函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO
3.1 函数执行前的一瞬间,生成AO活动对象
fun.AO = {
}
3.2 分析参数,形参作为对象的属性名,实参作为对象的属性值
fun.AO = {
num : 5
}
3.3 分析变量声明,变量名为属性名,值为undefined,如果遇到AO对象上属性同名,不去做任何改变
fun.AO = {
num : 5
}
3.4 分析函数声明,函数名为属性名,值为函数体,如果遇到AO对象上属性同名,则无情覆盖
4.逐行执行
综合分析:
<script type="text/javascript">
console.log(test);
function test(test){
console.log(test);
var test = 123;
console.log(test);
function test(){
}
console.log(test);
var test = function(){}
console.log(test);
}
test(10);
var test = 456
console.log(test);
</script>
预编译开始,先生成一个GO{
}
1.看变量GO{
test:underfined
}
2.看函数声明GO{
test:function test(test){
console.log(test);
var test = 123;
console.log(test);
function test(){
}
console.log(test);
var test = function(){}
console.log(test);
}
}
把整个函数体给test
预编译完成,开始执行代码,第二行的结果是test函数的函数体
3到13行都是函数声明,不用管
第14行函数执行,传入参数10
函数执行的时候产生AO{
}
1.看参数AO{
test:10
}
2.看变量,变量同名,不用管变量AO{
test:10
}
3.看函数,函数和参数同名,函数把参数覆盖AO{
test:function test(){}
}
4.逐行执行
第三行打印名字为test的函数体,
第四行给test赋值123,第五行打印123
7到9行函数体声明不用管
第十行打印123
第十一行把一个匿名函数(没有函数名的函数)赋值给test
第十二行函数执行完毕
第十四行回到全局,把456赋值给test
第十五行打印456
javascript预编译的过程的更多相关文章
- JavaScript 预编译与作用域
JavaScript 预编译与作用域 JavaScript 预编译的过程和作用域的分析步骤是 JS 学习中重要的一环,能够帮助我们知道代码的执行顺序,更好理解闭包的概念 预编译 JavaScript ...
- javaScript 预编译过程浅尝
javaScript 预编译过程 1.创建AO对象(Activation Object) AO{ a: } 2.找形参和变量声明,将变量和形参作为AO属性名,值为undefined AO{ a:und ...
- 关于JavaScript预编译和执行顺序以及函数引用类型的思考
昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了.问题抽象出来是这样的: <script > ...
- 重温JavaScript预编译的四个步骤
JS是解释型语言,运行过程分三步: 一.语法分析(检查代码是否存在语法错误): 二.预编译(代码执行之前,在内存中开辟空间,存放变量与函数): 三.解释执行(执行JS代码): 理解预编译的过程,对于理 ...
- javascript预编译和执行过程总结
javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块 ...
- JavaScript预编译过程理解
1-JavaScript运行三部曲 语法分析 预编译 解释执行 语法分析很简单,就是引擎检查你的代码有没有什么低级的语法错误: 解释执行顾名思义便是执行代码了: 预编译简单理解就是在内存中开辟一些空间 ...
- JavaScript预编译详解
一.js运行三部曲: 1.语法分析(通篇扫描看有没有语法错误) 2.预编译 3.解释执行 二.预编译前奏 1.imply global 暗示全局变量:任何变量如果未经声明就赋值,此变量为全局对象所有 ...
- Javascript - 预编译与函数词法作用域
预编译与函数词法作用域(Precompiled & Scoped) 预编译 Javascript脚本的宿主在执行代码之前对脚本做了预编译处理,比如浏览器对Js进行了预编译,编译器会扫描所有的声 ...
- JavaScript 预编译(变量提升和函数提升的原理)
本文部分内容转自https://www.cnblogs.com/CBDoctor/p/3745246.html 1.变量提升 console.log(global); // undefined var ...
随机推荐
- .net core Error -4090 EADDRNOTAVAIL address not available”
问题原因:IP地址错误或者网络未开
- 深度学习环境配置:Ubuntu16.04下安装GTX1080Ti+CUDA9.0+cuDNN7.0完整安装教程(多链接多参考文章)
本来就对Linux不熟悉,经过几天惨痛的教训,参考了不知道多少篇文章,终于把环境装好了,每篇文章或多或少都有一些用,但没有一篇完整的能解决我安装过程碰到的问题,所以决定还是自己写一篇我安装过程的教程, ...
- vue教程1-07 模板和过滤器
vue教程1-07 模板和过滤器 一.模板 {{msg}} 数据更新模板变化 {{*msg}} 数据只绑定一次 {{{msg}}} HTML转意输出 <!DOCTYPE html> < ...
- odoo开发环境搭建(二):安装Ubuntu 17虚拟机
odoo开发环境搭建(二):安装Ubuntu 17虚拟机 下载镜像文件: 配置网络: 安装vmware tools: 配置共享文件夹: 选中虚拟机,右键编辑设置里边配置共享文件夹,指定windows本 ...
- 以太坊ERC20代币合约案例
一.ERC20代币合约与web3调用 ERC20代币合约在小白看来觉得很高大上,但其实就是一个代币的定义标准,方便其他dapp统一调用各种代币的方法.如图: 二.ERC20合约标准 [官方链接] co ...
- 线程中的同步辅助类CountDownLatch
四个类可协助实现常见的专用同步语句.Semaphore 是一个经典的并发工具.CountDownLatch 是一个极其简单但又极其常用的实用工具,用于在保持给定数目的信号.事件或条件前阻塞执行.Cyc ...
- Android中Serializable和Parcelable序列化对象详解
学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Parcelable进行序列化操作 5.P ...
- 如何查看第三方apk的信息
很多时候,我们需要获取别人的apk的信息.但是我们看不到apk的代码,对于apk的信息并没有直接的方法获取.那么,我们要怎么获取apk信息呢? 这里,我整理了两个方法,亲测可用. 第一种,直接使用An ...
- GO入门——3. 控制语句
1 if 条件表达式没有括号 支持一个初始化表达式(可以是并行方式) 左大括号必须和条件语句或else在同一行 支持单行模式 初始化语句中的变量为block级别,同时隐藏外部同名变量 a := 1 i ...
- Spring Boot使用JWT实现系统登录验证
简介 什么是JWT(Json Web Token) jwt是为了在网络应用环境间传递声明而执行的一种基于json的开放标准.该token被设计紧凑且安全的,特别适用于SSO场景.jwt的声明一般被用来 ...