变量提升是指函数中的所有变量声明会在函数执行时被“提升”至函数体顶端。javascript的执行环境构建分为声明阶段和执行阶段。在声明阶段javascript引擎会为所有的变量和函数声明创建标识符。可以将此阶段看作是运行环境的前期配置.到了执行阶段,函数均已被定义,但是所有变量的值均未定义。
var x=1;
(function(){
consolel.log(x);
var x=2;
}());
看看上面的例子;我想大部分都会以为会住输出“1”;正确答案是“underfined”;其实上面的代码等价于:
var x=1;
(function(){
var x;//x=underfined
console.log(x);
x=2;
}());
函数声明和变量声明总是会被解析器悄悄地”提升”到方法体首部;比如:
function test(){
console.log(x);
var x=1;
}
//实际上被解释成这样
function(){
var x;
console.log(x);
x=1;
}
不过要注意,变量赋值并没有被提升,只是声明被提升了。但是,函数声明有点不一样,函数体也会一同被提升;但是请注意,函数的声明有两种方式: 1. 函数声明 2. 函数表达式
function a(){
b();//b is not a function
c();//c
var b=function(){
console.log("b");
};
function c(){
console.log("c");
}
}
a();
当变量声明与函数声明同名时,要注意覆盖问题
foo();//foo2
var foo=function(){
console.log("foo1");
};
function foo(){
console.log("foo2");
}
//实际上上面的代码解析成下面这样
var foo;
function foo(){//foo重新定义了
console.log("foo2");
}
foo();//foo2
foo=function(){
console.log("foo1");
};
----------
//如果顺序是下面这样的话,结果是:
var foo=function(){
console.log("foo1");
};
function foo(){
console.log("foo2");
}
foo();//foo1
//实际上上面的代码解析成下面这样
var foo;
function foo(){
console.log("foo2");
}
foo=function(){//重新赋值了
console.log("foo1");
};
foo();//foo1
console.log(typeof a);//Function
var a=1;
function a(){
console.log("a");
}
总结:
如果变量在函数体内声明,它的作用域是函数作用域。否则,它就是全局作用域。变量将会在执行进入作用域时被创建。块不会定义新的作用域,只有函数声明和程序才可以。变量在创建的时候会被初始化为undefined。如果变量声明语句带有赋值操作,则赋值操作只有在被执行的时候才会发生,而不是创建的时候。所以我们编码时应该先声明后使用。
下面有一道摘自最初的梦博客的题目:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
上面这道题输出什么;结果是“1”;上面的代码等价于:
var a = 1;
function b() {
function a() {}
a = 10; //此的a并不是全局变量a;而是对函数a重新赋值为10;
return;
}
b();
alert(a);