我们先来看下面这段代码会输出什么内容呢?
var a=1;
f();
console.log(a);
function f(){
console.log(a);
var a=2;
console.log(a);
}
//输出结果:
undefined
2
1
这是变量提升的经典例子,涉及到函数声明和var变量声明两种提升方式,如果对输出结果理解有困难,follow本文一起学习吧!
1. 什么是变量提升
变量提升就是对于所有的变量的声明语句,都会提升到当前作用域的头部。正是由于变量提升,因此var声明的变量或函数声明可以先使用后声明,如下图,ES5中的变量提升包含两种:(1)var声明的变量(2)函数,而函数的提升又分为函数声明和函数表达式。
2. var声明的变量
下面这段代码是用var声明变量,会输出什么呢?
function f(){
console.log(a);
var a=2;
}
f();
//输出结果:
undefined
js会对var声明的变量进行变量提升,仅将其声明提升到函数作用域的头部,等价于
function f(){
var a;
console.log(a);
a=2;
}
f();
注:没有var声明的变量会变成全局变量,也不具备变量提升的特性。
3. 函数
函数分为函数声明(function+函数名)和函数表达式(将匿名函数赋值给变量),我们重点讲解函数和变量同时提升的问题。
当函数声明和变量同时提升,
console.log(f);
function f(){
}
var f=1;
//输出结果:
function f(){}
当函数表达式和变量同时提升,
console.log(f);
var f=function(){};
var f=1;
//输出结果:
undefined
为什么会出现两种不同的输出结果呢?
这是因为函数提升分为两种情况:
- 函数声明:在提升时,会连同定义整个被提升上去,并且函数声明的优先级高于变量声明,等价于
var f;
f = function (){
}
console.log(f);
f=1; //变量声明只进行一次,因此function f()声明后,var f=1的声明会被忽略
- 函数表达式:其实就是var声明的变量,因此看作是两个var变量就好了,等价于
var f;
console.log(f);
f = function(){};
f = 1;
4. 总结
1. 所有声明都会被提升到当前作用域的最顶部
2. 同一个变量声明只进行一次
3. 变量提升的优先级:函数声明 > 函数表达式 = var声明的变量
4. 函数声明的变量提升是连同定义一起,而其余两种只提升声明、不提升初始化
本文是参考多篇博客之后总结的看法,与君共勉,如有错误欢迎指正。