函数声明与变量声明的提升

js中存在变量声明与函数声明提升的情况,再加上目前的ES5标准中没有块级作用域的概念。所以,可能会出现与你本意不相符合的执行情况。

注意语句块中的变量声明

因为ES5中没有块级作用域,所以你需要注意你的变量声明,它会在你的第一句代码执行之前就已经声明完毕了:

if(!("a" in window)){
    var a = "123";
}
console.log(a);  //"undefined"

这段代码的本意是先判断全局对象window中是否含有变量a,如果没有变量a,就声明变量a,并赋值为“123”;但是在js执行的时候,由于有的变量提升的概念,所以你的到的并不是你要的结果,上段代码实际解析为:

var a;  //此时a为undefined
if(!("a" in window)){  //判断语句结果为false
    a = "123";
}
console.log(a);

变量声明与函数声明

除了变量声明之外,还有一种是函数声明,我们知道函数的定义方法有函数声明和函数表达式,其实这两种方法都只是变相的为匿名函数赋值而已:

function a(){
    //...somecode
}

var a = function(){
    //...somecode
}

一般情况下这两种方式所获得的结果都是一样的。但是有了提升的概念,他们的执行方式也是不一样的:

function test(){
    console.log(typeof a);
    function a() {
    };
}
test();  //"function"

function test(){
    console.log(typeof a);
    var a = function() {
    }
}
test();  //"undefined"

为什么会出现这样的情况,这就是函数声明和函数表达式的区别了,函数表达式在解析的时候,a会被当作变量然后提升到函数的顶端,然而匿名函数并没有被提升,所以typeof 返回的仍然是 undefined。 但是声明函数就不一样了,它会整个都提升到顶端,所以返回的值是 function;