JavaScript的变量及函数声明提升及预解析

JavaScript引擎在执行的时候,会在相应代码段寻找var声明的变量及函数声明(函数表达式不会提升),把所有变量和函数的声明都提升到当前作用域的最前面。此时变量是未赋值的(undefined),当执行到相应代码段才会赋值,函数是其本身。

并且有以下一些坑:

1.变量声明及函数声明预解析时,变量解析为undefined,函数解析为其本身。预解析时函数声明优先级高于变量声明,函数声明会覆盖变量声明,但不会覆盖变量赋值。如果声明变量的同时初始化或赋值那么变量优先级高于函数。

例1:预解析时,变量解析为undefined,函数解析为其本身,函数声明会覆盖变量声明,故1行输出如下结果。变量赋值覆盖函数,故6.7行结果如下。

1 console.log(a);     // function a(){console.log(2);  }
2 var a = 1;
3 function a(){
4     console.log(2);    
5  }
6  console.log(a);    //1
7  a();    //无法执行

例2:变量a预解析为undefined。fn1运行时沿着作用域链找到8行变量a,但该a在fn1后面故没有赋值,输出undefined。fn同样找到相同未赋值的变量a,输出undefined。

11行根据作用域链输出的是全局变量a。

 1 var a =1;
 2 function fn(){
 3    console.log(a);
 4    function fn1(){
 5        console.log(a);
 6     }
 7     fn1();
 8     var a =2;
 9 }
10 fn();    //undefined    undefined
11 console.log(a);    //1

2.没有使用var声明的变量为全局变量,预解析时没有使用var声明的同名变量会被隐藏。

例:预解析时8行变量a声明隐藏,fn1及fn运行时沿着作用域链找到全局变量a声明。并且在8行时全局变量a重新赋值。

 1 var a =1;
 2 function fn(){
 3    console.log(a);
 4     function fn1(){
 5         console.log(a);
 6      }
 7      fn1();
 8      a =2;
 9  }
10  fn();    //1  1
11  console.log(a);    //2

3.函数形参相当于变量声明。

例:函数fn的形参相当于变量声明var a ,预解析为undefined,故7行运行时沿作用域链找到未赋值的变量a。

1 var a = 1;
2 function fn(a){
3   alert(5);
4   alert(a);
5 
6 }
7 fn();    // 5   undefined
8 alert(a);    //1
9 fn(a);    //5    1

4.仅仅声明某一个函数,引擎并不会对函数内部的任何变量进行查找或赋值操作。只会对函数内部的语法错误进行检查。

所以循环语句的声明:

1 for(var i=0; i<10; i++) {
2     result[i] = function(){
3       return i;
4   }
  }

 我原本以为它是这样的:

1 result[0] = function() { return 0;};
2 result[1] = function() { return 1;};
3 result[2] = function() { return 2;};
4 ......

 实际上它是这样的:

1 result[0] = function() { return i;};
2 result[1] = function() { return i;};
3 result[2] = function() { return i;};
4 ......

故下例:

 1 function createFunctions() {
 2     var result = newArray();
 3     for(var i=0; i<10; i++) {
 4         result [i] = function() {
 5             return i;
 6          }
 7      }
 8     return result;
 9 }
10 var foo = createFunctions();
11 console.log(foo[0]());    //10                   

 

posted @ 2017-01-17 00:33  孔zheng  阅读(1252)  评论(0编辑  收藏  举报