JS运行三部曲(预编译)
JS运行的三个步骤:
- 语法分析
- 预编译
- 解释执行
语法分析:通俗来说就是通篇检查你的代码有没有语法错误,有语法错误的话,程序是不会执行的
解释执行:也就是程序读一句执行一句
最重点的也就是预编译了,那么预编译到底是什么?它发什么在什么时候?
先来段代码压压惊
function fn (a) {
console.log(a)
var a = 123;
console.log(a)
function a () {}
console.log(a)
console.log(b);
var b = function () {}
console.log(b);
function d () {}
console.log(d)
}
fn(1)
这是打印结果
ƒ a() {}
123
123
undefined
ƒ () {}
ƒ d() {}
是不是有些地方有点懵逼和意外,其实这就是预编译捣的鬼,预编译就是在函数执行之前,在你的内存中申请一点空间,存放变量和函数
下面说说预编译到底是怎样的过程,也就是上面函数到底发生了什么
预编译过程:
- 创建AO对象(Active Object)
- 找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined
- 将实参与形参统一(把实参值赋予形参)
- 在函数体里找函数声明,把函数声明也作为AO对象的属性名,值为函数体()
上面那段代码,fn函数执行之前,先发生预编译过程
第一步
AO = { }
第二步
AO = {
a:undefined,
b:undefined
}
第三步
AO = {
a:1,
b:undefined
}
第四步
AO = {
a:function (){},
b:undefined,
d:function (){}
}
第四步代表预编译完成,然后函数执行
AO = {
a:123,
b:function (){},
d:function (){}
}
function fn (a) {
console.log(a) //这时函数未执行,打印function a(){}
var a = 123; //此时执行了a=123
console.log(a) //打印123
function a() {}
console.log(a) //打印123
console.log(b); //此时函数未执行,打印undefined
var b = function () {}
console.log(b); //此时执行了 b=function(){},打印function(){}
function d () {}
console.log(d) //打印function d(){}}
}
fn(1)
举几个‘栗子’
//1.
function fn(a,b) {
console.log(a); //打印1
c = 0;
var c;
console.log(b); //打印function b() {}
a = 3;
b = 2;
console.log(b); //打印2
function b() {};
function d() {};
console.log(b) //打印2
}
fn(1);
//2.
console.log(bar()); //打印function foo() { //body }
function bar(a,b) {
return foo;
foo = 10;
function foo(){
//body
}
var foo = 11;
}
//3.
console.log(bar()); //打印11
function bar(a,b) {
foo = 10;
function foo(){
//body
}
var foo = 11;
return foo;
}
以上是单个函数发生的预编译和函数执行过程,那么在<script></script>整个脚本中,是怎么样的呢?
<script type="text/javascript">
var a = 1;
function b () {
var x = 3;
function d () {}
}
var c = function () {
var y = 4;
}
</script>
同样的过程,在语法分析之后,开始预编译,不过此时预编译创建的叫GO对象,(Global Object)
GO/window = {
a:undefined,
c:undefined,
b:function b () {
var x = 3;
function d () {}
}
}
函数执行:
GO/window = {
a: 1,
c: function () { var y = 4; },
b: function b () {
var x = 3;
function d () {}
}
}
在执行b函数之前,将b函数预编译,也就是创建b函数的AO对象
如果有两个<script></script>呢?那就先执行完一个,再执行下一个。
注意问题:
预编译只有变量声明、函数声明,并不会发生赋值,赋值发生在执行阶段
匿名函数function (){ } 不参与预编译
JS运行三部曲(预编译)的更多相关文章
- js中的预编译
预编译 js执行顺序: 词法/语法分析 预编译 解释执行 js中存在预编译 function demo() { console.log('I am demo'); } demo(); //I am d ...
- js - 基础 之 预编译总结
js运行步骤 语法解析(检查有无语法错误) 预编译 解释运行(将 js 翻译成计算机识别的语言(0.1组成),翻译一行执行一行) 预编译 [全局]: 创建 GO( Grobal Object ) 对象 ...
- JS作用域和预编译(转载 学习中。。。)
JS在页面加载过程中顺序执行.但是分块预编译.执行. JS在执行前会进行类似”预编译”的操作,而且先预声明变量再预定义函数. 此时注意,是声明,不是定义,如:var a = 1; 在预编译中,只是执行 ...
- js复习,预编译
注意:函数声明整体提升.变量 声明提升 1.imply global 暗示全局变量:即任何变量,如果变量未声明就赋值,此变量就为全局对象所有 ==> eg: a = 122;==> e ...
- js三部曲---预编译
函数内:1,创建AO对象//Activation Object 2,找函数内形参和变量声明,将其作为AO对象的属性名,值为undefined. 3,实参赋到AO对象 形参名里 4,在函数体里找函数声明 ...
- gulp最佳实践(包含js,css,html预编译,合并,压缩,浏览器自动刷新)
gulp是基于流的自动化构建工具官方网址:http://www.gulpjs.com.cn/ 一.安装需要的模块 1.新建package.json,输入下面的内容 { "name" ...
- JS预编译详解
我们都知道javascript是解释型语言,执行的特点呢是编译一行,执行一行.按照这个思路有时候我们在运行代码时会有一些令人费解的现象出现.下面我们一起来执行下面三段代码. <script> ...
- JS的预编译和执行顺序 详析(及全局与局部变量)
最近在复习javascript的事件处理时发现了一个问题,于是总结一下:javascript的预编译和执行顺序的问题: <html> <head> <title> ...
- JS的预编译和执行顺序 详析
原文:JS的预编译和执行顺序 详析 最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题 代码: 复制代码 代码一 <ht ...
随机推荐
- 【分布式】ZooKeeper权限控制之ACL(Access Control List)访问控制列表
zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机制来解决访问权限问题,详见官网文档:ht ...
- @Value("#{}")与@Value("${}")
开发过程中,有些配置信息是根据环境的不同而有不同的值.这个时候,我们需要获取配置文件中的值或者spring容器中的值,可以通过@value注解获取相关的值. @Value("#{}" ...
- 用oracle中的Row_Number实现分页
Row_Number实现分页 1:首先是 select ROW_NUMBER() over(order by id asc) as 'rowNumber', * from table1 生成带序号 ...
- 【Java 基础】Java日期格式问题
1. Use SimpleDateFormat to format Date. Watch out, SDF is NOT THREAD-SAFE, it might not be important ...
- 使用Booststrap布局网页页面
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="utf-8&qu ...
- 【MySQL】学生成绩
统计每个人的总成绩排名 select stu.`name`,sum(stu.score) as totalscore from stu GROUP BY `name` order by totalsc ...
- 聊聊 SpringBoot 中的两种占位符:@*@ 和 ${*}
前言 在 SpringBoot 项目中,我们经常会使用两种占位符(有时候还会混用),它们分别是: @*@ ${*} 如果我们上网搜索「SpringBoot 的占位符 @」,大部分答案会告诉你,Spri ...
- BDD自动化测试框架cucumber(1): 最基本的demo
BDD(Behavior Driven Development),行为驱动开发, 对应自动化测试框架,python有behave,java有cucumber, 这次记录cucumber+springb ...
- [BUUCTF]REVERSE——[FlareOn4]IgniteMe
[FlareOn4]IgniteMe 附件 步骤: 例行检查,32位程序,无壳 32位ida载入 当满足第10行的if条件时,输出G00d j0b!提示我们成功,看一下sub_401050函数 3.s ...
- UVA12412 师兄帮帮忙 A Typical Homework (a.k.a Shi Xiong Bang Bang Mang) 题解
Content 自己去看题面去. Solution 算不上很繁琐的一道大模拟. 首先,既然是输出 \(0\) 才退出,那么在此之前程序应当会执行菜单 \(\Rightarrow\) 子操作 \(\Ri ...