JavaScript 有一些特点:1.跨平台 2.弱类型 3.解释执行(逐行执行)
在JavaScript运行时,会按顺序进行一些步骤
1.先对代码进行语法分析,所谓语法分析,作用是 检查代码有没有基本的语法错误,例如单词拼写 ,括回,等。
2.词法分析(预编译)
3.逐行执行
下面我们就深入了解一下第二步词法分析(预编译)
预编译过程一般分为两种情况
全局 和 局部
1.全局 指的是直接在script标签中的代码,不包括函数执行部分的代码
例子:
<script>
var a = 100;
var b = 200;
var c = 300;
function a(){}
function fun(){}
</script>
执行前:
1.在window对象下生成一个GO(global object)对象
GO = {
自带的属性这里省略不写
}
2.分析 变量声明,变量名为属性名,值全为undefined
GO = {
a : undefined,
b : undefined,
c : undefined
}
3.分析 函数声明(而不是函数表达式)函数名为属性名,值为函数体,如果函数名和变量名相同,则无情覆盖(如例子中的 var a 和 function a(){})
GO ={
a : function a(){},
b : undefined,
c : undefined,
fun : function fun(){}
}
此时,GO就是预编译完成的最终对象,词法分析结束
最后一步逐行执行
已经被词法分析分析过的语句就可以不管了,专心赋值
此时 GO = {
a : 100, // 赋值时 var a = 100 讲 a属性值再次改变
b : undefined,
c : undefined,
fun : function fun(){}
}
2.局部 函数执行的时候进行的
例子:
<script>
var num = 100;
function fun(num){
console.log(num)
}
fun(5)
</script>
执行前
1.预编译过程
GO = {
num:undefined,
fun : function fun(num){...}
}
2.执行过程
GO = {
num : 100,
fun : function fun(num){...}
}
3.函数调用过程:函数调用时也会生成自己的作用域(AO:action object)函数调用时候,执行前的一瞬间产生的,如果有多个函数的调用,会产生多个AO
3.1 函数执行前的一瞬间,生成AO活动对象
fun.AO = {
}
3.2 分析参数,形参作为对象的属性名,实参作为对象的属性值
fun.AO = {
num : 5
}
3.3 分析变量声明,变量名为属性名,值为underfind,如果遇到AO对象上属性同名,不做任何改变
fun.AO = {
num : 5
}
3.4 分析函数声明,属性名为属性名,值为函数体,如果遇到AO对象上属性同名,则无情覆盖
最后 逐行执行。
下面给出一个例子
function test(){ console.log(b); if(a){ var b = 100; } c = 123; console.log(c); } var a; test(); a = 20; test(); console.log(c);
1.生成GO
GO = { }
2.分析变量声明
GO = {
a : undefined
}
3.分析函数声明
GO = {
a : undefined,
test : function
}
4.逐行执行
4.1 test调用
4.1.1 生成test.AO = { }
4.1.2 分析参数 没有
4.1.3 分析变量声明
test.AO = {
b : undefined
}
4.1.4 分析函数声明 没有
4.1.5 结果
test.AO = {
b : undefined
}
继续逐行执行
4.2 a 的值改变
GO = {
a : 20,
test : function,
c : 123
}
4.3 test调用 生成test.AO = { }
4.3.1 参数 没有
4.3.2 变量声明
test.AO = {
b : undefined
}
4.3.3 函数声明 没有
4.3.4 结果
test.AO = {
b : undefined
}
4.3.5 继续执行
test.AO = {
b : 100
}
可以清楚的看出每个属性的值为多少了