在ES6之前,JavaScript没有块级作用域的概念(一个’{}'就是一个块级作用域),只有全局作用域和函数作用域。变量提升既将变量(或函数)声明提升到它所在作用域最开始的部分:
(1)变量提升
console.log(a);//undefined
var a = 'xxx';
console.log(a); // xxx
//console.log(b);//报错( b is not defined)
function fn() {
console.log(a);//undefined
var a = 'yyy';
console.log(a);//yyy
console.log(b);//报错( b is not defined)
}
fn();
由于变量的提升,上面的代码其实是这样执行的:
var a ;
console.log(a);//undefine
a = 'xxx';
console.log(a);// xxx
console.log(b);// b is not defined
{
var a ;
console.log(a);//undefined
a = 'yyy';
console.log(a);//yyy
console.log(b);//b is not defined
}
(2)函数提升
JS创建函数有两种方式:函数声明式和函数字面量式。
只有函数声明才存在函数提升:
console.log(f1);//function f1(){}
console.log(f2);//undefined
function f1() {};
var f2 = function(){};
实际执行顺序如下:
function f1() {};
var f2;
console.log(f1);//function f1() {}
console.log(f2);undfined
f2 = function () {};
函数字面量式创建函数类似于变量的声明,所以通过字面量式创建的函数的提升类似于变量提升。
(3)test
console.log(f1);
console.log(f2);
function f1(){console.log('xxx')};
var f2 = function() {};
(function() {
console.log(a);
a = 'yyy';
var a = 'zzz';
console.log(a);
})()
实际执行顺序
function f1() {
console.log('xxx');
}
var f2;
console.log(f1);//f1() {...}
console.log(f2);//undefined
{
var a;
console.log(a);//undefined
a = 'yyy';
a = 'zzz';
console.log(a);//zzz
}