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;