代码1:
<script> console.log(typeof a2)//undefined var a2=‘littlebear‘; console.log(a2)//littlebear </script> <script> console.log(typeof a2)//string var a2=1; console.log(a2)//1 </script>
代码2:
<script> console.log(typeof a2)//undefined var a2=‘littlebear‘; console.log(a2)//littlebear console.log(typeof a2)//string var a2=1; console.log(a2)//1 </script>
代码3:
<script> console.log(typeof a)//undefined console.log(a)//报错,遇到<script>标签对时,会先对这一块进行预解析,下面没预解析,所以找不到声明过的a,于是报错了 </script> <script> console.log(typeof a)//undefined var a=1; console.log(a)//1 </script>
第一个script标签里的a,undefined,直接输出啊,立马报错。因为在第一个script标签的时候没有发现a声明过,没声明直接使用就会报错。 第二个script标签里面的输出是我们预料之中的
得出一个结论:js的预编译,是从有顺序的,根据script标签的顺序从上到下执行的。
例如:
<script> function fn(a,b){ console.log(a)//容易上当 var a=10; console.log(a)//10 } fn(‘容易上当‘); </script>
<script> var a=10; function fn(a,b){ console.log(a)//function a(){} 这里输出function a(){}, 不是参数a的值,哈哈 var a=10; console.log(a)//10 function a(){} console.log(a)//10 } fn(15); </script>
参数a会覆盖预编译变量a的默认值,如果有函数,函数会覆盖参数a的值,这个就是先后顺序而已
<script> function fn(){ function a(){console.log(1)} return a; function a(){console.log(2)} } fn()();//2 </script>
由于预编译,后面的a覆盖了前面的a,所以return a的值 其实就是预编译之后a的值,预编译之后a的值就是第二个a。
var a=10; function fn(){ //预编译a 赋值undefined,内部作用域存在a这个变量,所以这里 !a 就是 !undefined,就是true,进入函数a=20; //但是后面的a怎么就是20呢,js没有块级作用域!! 不要小看js各种细节,够折腾的 if (!a) { var a=20 } console.log(a)// 这里是20 , } fn()
//a in window ==>true 、 !true ===》false if (!(a in window)) { var a = 1; } console.log(a)// undefined
原文:http://www.cnblogs.com/web-fusheng/p/6838875.html