为什么要讲变量提升,首先看一个小测试,如果你答错了,那就说明你需要了解一下变量提升的机制
0 测试
看看下面分别输出多少?
console.log(x); // -> ?
var x = 5;
console.log(x); // -> ?
console.log(y); // -> ?
答案是:
第二个log为5,可以理解,第一个undefined也可以理解,为什么最后的y是error呢?
因为Javascript engine 在运行代码前,会重新调整代码的结构,提升了变量x的声明,上面的代码在运行前结构大体变成了这样
var x;
console.log(x); // -> undefined
x = 5;
console.log(x); // -> 5
console.log(y); // -> Uncaught ReferenceError: y is not defined
1 变量提升
只有变量声明如var = x会被提升的代码的顶部,变量的赋值如var x = 10不会被提升;
没有使用变量声明关键字如var,let, const等的变量声明也不会被提升
console.log(x);
console.log(y);
var x = 'This will log "undefined"!';
y = 'This will throw an error :(';
2 函数提升
函数提升有点不同,有两种定义函数的方式:函数表达式和函数声明
函数表达式: 类似变量提升,fn被提升到代码顶部,并且值为undefined,之后fn被赋值函数
var fn = function() {
// do something...
}
函数声明: 整个代码块都会被提升,变量fn就是函数本身,会被提升到最顶部,甚至在变量声明之前
function fn() {
// do something...
}
示例:
fnDeclaration(); // -> This works!
fnExpression(); // -> Uncaught TypeError: fnExpression is not a function
function fnDeclaration() {
console.log('This works!');
}
var fnExpression = function() {
console.log("This won't work :(");
}
3 示例
变量提升前的代码
var a = 123;
var b = 'abc';
var fnExpression = function() {
var c = 456;
var d = 'def';
}
function fnDeclaration() {
var e = 789;
}
变量提升后的代码
function fnDeclaration() {
var e;
e = 789;
}
var a;
var b;
var fnExpression;
a = 123;
b = 'abc';
fnExpression = function() {
var c;
var d;
c = 456;
d = 'def';
}
总结:
先声明总是对的,函数提升有点意思,函数表达式和变量声明很像,函数声明才最靠前
参考资料:《Step Up Your JS: A Comprehensive Guide to Intermediate JavaScript》