js作用域链和预编译
js引擎运行分为两步,预解析 代码执行
(1)预解析: js引擎会拿js里面所有的var还有 function 提升到当前作用域的最前面
(2)代码执行:按照代码书写的顺序从上往下执行
预解析分为:变量预解析(变量提升)和函数预解析(函数提升)
变量提升就是把所有的变量声明提升到作用域的最前面,不提升赋值操做
函数提升:就是把所有函数提升到作用域的最前面,不调用函数
下面有几个小题目,大家先尝试着思考并且得出答案,有疑问的话可以看问题后面注释部分的解析。每次在浏览器控制台测试一个题目时,记得注释其他题目哦,否则会相互影响。
解题思路:先预解析,再根据作用域链查找
1 <script> 2 3 //问题1 变量预解析(变量提升)第一种情况 4 console.log(num1); 5 var num1 = 10; 6 //结果undefined 7 8 9 /* 相当于执行了以下代码 10 var num1; 11 console.log(num1); 12 num1 = 10; */ 13 14 15 16 17 // 问题2 变量预解析(变量提升)第二种情况 18 fun1(); 19 var fun1 = function() { 20 console.log("这里测试变量预解析"); 21 } 22 /* 相当于执行了以下代码 23 var fun1; 24 fun1(); 25 fun1 = function() { 26 console.log("这里测试变量预解析"); 27 } */ 28 29 30 // 问题3 31 fun2(); 32 33 function fun2() { 34 console.log("函数预解析"); 35 } 36 37 /* 相当于执行了以下代码 38 function fun2() { 39 console.log("函数预解析"); 40 } 41 fun2(); */ 42 43 44 // 预解析案例1 45 var num = 10; 46 fun3(); 47 48 function fun3() { 49 console.log("fun3" + num); 50 var num = 20; 51 } 52 53 /* 相当于执行了以下代码 54 var num; 55 56 function fun3() { 57 var num; 58 console.log(num); //先变量提升,然后根据作用域链查找 59 num = 20; 60 61 } 62 num = 10; 63 fun3(); */ 64 65 66 // 案例2 67 var num4 = 10; 68 69 function fun4() { 70 console.log("fun4" + num4); 71 var num4 = 20; 72 console.log("fun4" + num4); 73 } 74 fun4(); 75 76 /* 相当于执行了以下代码 77 var num4; 78 79 function fun4() { 80 var num4; 81 console.log(num4); 82 num4 = 20; 83 console.log(num4); 84 } 85 num4 = 10; 86 fun4(); */ 87 88 89 90 // 案例3 91 var a = 18; 92 fun5(); 93 94 function fun5() { 95 var b = 9; 96 console.log(a); 97 console.log(b); 98 var a = '123'; 99 } 100 101 102 /* 相当于执行了以下代码 103 var a; 104 function fun5() { 105 var b; 106 var a; 107 b = 9; 108 console.log(a); 109 console.log(b); 110 a = '123'; 111 } 112 a = 18; 113 fun5(); */ 114 115 116 // 案例4 117 fun6(); 118 console.log("fun6 " + p); 119 console.log("fun6 " + n); 120 console.log("fun6 " + m); 121 122 function fun6() { 123 var a = b = c = 9; 124 console.log("fun6 " + m); 125 console.log("fun6 " + n); 126 console.log("fun6 " + p); 127 } 128 129 130 /* 131 相当于执行了以下代码 132 133 function fun6() { 134 // 注: var m = n = p = 9; 相当于 var m = 9; n = 9; p = 9; 所以n p 直接赋值,是全局变量 135 136 // 而 var m = 9, n = 9, p = 9; 相当于 var m = 9; var n = 9; var p = 9; 137 var m; 138 m = 9; 139 n = 9; 140 p = 9; 141 142 console.log(m); 143 console.log(n); 144 console.log(p); 145 } 146 fun6(); 147 console.log(p); 148 console.log(n); 149 console.log(m); */ 150 </script>