对声明提升的一点思考。

302 查看

javascript变量和函数由一个很重要的特性是声明提升。声明提升是什么意思呢?即浏览器在解释js代码之前会有一个预读阶段,将由var声明的变量和函数提升到当前作用域的顶端。举个实际的例子:、

    console.log(bbb); //function bbb() {console.log(aaa);}
    console.log(aaa);//undefined
    count = 0;
    for (i = 0; i < 1000; i ++) {
        count += i;
    }
    var aaa = 0;
    bbb = 20;
    function bbb() {
        console.log(aaa);
    }
    console.log(bbb());//**报错**

为什么会出现这样的情况呢?这就是js在执行代码之前的预读阶段进行了声明提升,提升之后的代码实际上是:

    function bbb() {
        console.log(aaa);
    }
    var i, aaa;
    console.log(bbb);
    console.log(aaa);
    count = 0;
    for ( i= 0; i < 1000; i ++) {
        count += i;
    }
     aaa= 0;
    bbb = 20;
    console.log(bbb());

代码变成了这样,是不是一目了然了。为什么函数在最前面,因为它是js中的一等公民,其他最多是人民。这就是我今天要讲的内容的基础,下面正式进入主题。

在很多时候,声明提升会有用,可是在很多时候会让程序看上去生涩难懂,特别是程序很长时就更是难以预料。解决方法有很多,主流的是采用命名空间和用var方式声明函数。看下面的代码:

    var a = 1;
    var b = 1;
    var aaa = function() {
        var a = b = 2;
    }
    aaa();
    console.log(a);//1
    console.log(b);//2

这里又是怎么回事呢?因为使用var a = b = 2;这种方式声明的变量,第一个由于有var所以是局部变量,第二个没有var所以是全局变量(是不是觉得太不机智了)。这里就引出了下一个问题,请看下面的代码:

 var a = 1;
    var b = 1;
   var aaa = function() {
       var a = b = function() {console.log(222);};
   }
    aaa();
    console.log(a);//1
    console.log(b);//function() {console.log(222);};

这个结果的确理所当然,可是总是觉得世界本来不该是这个样子,有没有?