变量提升(Hoisting):在ES6之前,函数声明
和变量声明
总是被JavaScript解释器隐式地提升(hoist)到包含他们的作用域的最顶端。
注意: 1. JavaScript 仅提升声明,而不提升初始化。2. ES6 中不存在变量提升的概念。
1. 变量提升
变量未声明:
function fn () { console.log(name);}fn(); // 报错: ReferenceError: name is not defined
变量在使用后声明:
function fn () { console.log(name);; // undefined var name;}fn();
变量在使用后声明并初始化:
function fn () { console.log(name);; // undefined var name = 'cedric';}fn();
上面函数等效于下面:
function fn () { var name; console.log(name);; // undefined name = 'cedric';}fn();
2. 函数表达式的提升
function fn () { console.log(fn2);; // undefined console.log(fn2());; // 报错 Error: fn2 is not a function var fn2 = function() { };}fn ();
可见,在一个函数表达式声明前,可以访问其函数名,但是调用此函数会报错!!
3. 函数声明的提升
function fn () { console.log(fn2); // fn2() {console.log('console in fn2');} fn2(); // console in fn2 function fn2() { console.log('console in fn2'); };}fn ();
在函数声明前,既可以访问函数名,也可以调用此函数。
4. 易错
var a = 1;function fn() { console.log( a); // undefined var a = 2;}fn();
var a = 1;function fn() { console.log( a); // 1 a = 2;}fn();
var a = 1;function fn() { if (!a) { var a = 2; } console.log( a); // 2}fn();
var a = 1;function fn() { if (!a) { a = 2; } console.log( a); // 1}fn();