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.fn2 var 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);//undefined var 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