js是解释型语言,读取一段执行一段
js执行的时候一般分为两个时期:预编译期、执行期
执行期:基本就是按照逻辑从上往下执行;
预编译:一般都发生代码执行前,大体来算一共有4个阶段:
1> 先创建一个全局GO(Global Object)(window对象)
2> 变量的声明被提升,并对变量赋值undefined
3> 统一实参和形参,把实参的值付给形参
4> 函数的声明被提升;
js在预编译过程中浏览器只会获取函数的名字,不会对函数里的内容进行编译;
所以就算函数里的语法出现错误,只要该函数不执行,就不会报错。
函数执行时才会预编译
函数预编译生成的时AO(Active Object、活动对象)
AO和GO就是拿来存储东西的
arguments对象是函数执行时用来传参和存储数据的对象
!
!
!
<script>
console.log(a); //undefined
var a; //变量声明
a = 10; //赋值
console.log(a); //10
</script>
说明js变量声明被提升(就当是他被放到前面(仅仅只是声明被放到前面)),执行时从上往下执行
注:变量的声明和赋值是两个步骤
<script>
console.log(a); //undefined
var a = 10; //变量声明 并赋值
console.log(a); //10
</script>
<script>
console.log(a); //function a(){} //1
var a; //变量声明 //2
a = 10; //3
console.log(a); //10 //4
function a(){} //5
</script>
对一次在控制台打印a最终结果是function a(){}
遵循上面4个步骤的
预编译到第2行时
AO = {
a:undefined
}
预编译到第5行时
AO = {
a:function a(){}
}
所以执行第1行时a打印出的function a(){}
在执行第3行时 a 被赋值 所以第4行执行时打印10
<script>
var a;
function a(a){
console.log(a); // 5
var a;
console.log(a); // 5
a = 10;
console.log(a); // 10
}
console.log(a);// function a(){********}
a(5)
</script>
实参也形参统一(实参的值赋给形参)
由于时函数执行所以生成的是一个活动对象(AO)
function a编译时还是按照之前的
GO = {
a:undefined
}
执行时从上往下
对比一下就很清楚了
<script>
var a;
function a(a){
console.log(a); // undefined
var a;
console.log(a); // undefined
a = 10;
console.log(a); // 10
}
console.log(a);// function a(){********}
a()
</script>
函数在执行时会生成一个[Arguments Object]用来存储传进来的参数
<script>
function a(a){
console.log(arguments);
var a;
console.log(arguments);
a = 10;
console.log(arguments);
}
a(5,55)
</script>
<script>
function a(a){
console.log(arguments);
var a;
console.log(arguments);
}
a(4,55)
</script>
说明
arguments中实参和形参是绑定在一起的,占用同一个内存空间