JS执行过程
1、首先是预解析:预解析过程最重要的是提升,在JavaScript代码在预解析阶段,会对以var声明的变量名,和function开头的语句块,进行提升操作
2、执行操作
全局中解析和执行过程
<script>console.log(a);//undefined===>window.a console.log(b);//b is not defined console.log(fn1);//会打印函数===>window.fn1 console.log(fn2);//undefined===>window.fn2var a = 1;b = 2;function fn1() {console.log('函数1');}var fn2 = function () {console.log('函数2');} </script>
<script>var a;console.log(window); </script>
<script>var a = 1;console.log(window); </script>
上述例子有变量有函数(在全局作用域下):
1、对于有var声明的函数,就等同于window.a,相当于在js第一次扫描代码时候(预解析),给window添加了一个a的属性,但是没有赋值,所以打印结果是undefined
2、对于没有var声明的函数,在js第一次扫描代码时候(预解析)不会给windouw添加任何属性,所有会直接报错
3、对于以function开头的函数,就等同于window.fn1,相当于在js第一次扫描代码时候(预解析),给window添加了一个fn1的属性,而且是直接赋值的(函数的引用),所以打印结果是一个函数
4、对于没有以function开头的函数(也就是函数表达式),其过程相当于var a的过程,在js第一次扫描时(预解析),给window添加了一个fn2的属性,但是没有赋值,所以打印结果是undefined
命名冲突
<script>console.log(f);//打印函数var f = 1;function f(){console.log('foodoir');} </script>
<script>console.log(f);//打印函数function f(){console.log('foodoir');}var f = 1; </script>
<script>console.log(f);//undefinedvar f = 1;var f = 2; </script>
<script>console.log(f);//打印第二个函数function f(){console.log('foodoir');}function f(){console.log('hello world');} </script>
1、函数与变量命名冲突时,变量会被直接忽略,保留的永远的都是函数
2、函数与函数命名冲突时,最后的函数会替换之前的函数
3、变量与变量命名冲突时,永远都是undefined
函数中的解析与执行过程
<script>function f(a, b) {alert(a);alert(b);var b = 100;function a() {}}f(1, 2);//依次弹出function a(){}以及2 </script>
<script>function f(a, b) {alert(a);alert(b);var b = 100;function a() {}}f(1);//依次弹出function a(){}以及undefined </script>
函数中的解析过程与全局类似
1、在第一次扫描js代码时,首先会将a变量提升,但是扫描到最后发现有函数a,这里有命名冲突,那么就会直接将变量忽略
2、b变量没有命名冲突,但是第一次扫描后,b只是提升并没有赋值,所以上面代码段一中,正式执行代码的时候就会弹出2