# 声明提升(Hoisting)
在JavaScript中,函数以及变量的声明都将被提升到函数的最顶部。也就是变量可以使用后再声明
x = 5;
console.log(x);
var x
这是因为“Hoisting”——声明提升
函数声明和变量声明总是会被解释器“提升”到方法体的最顶部
# 1.不会提升初始化
// 第一组代码
var x = 5;
var y = 7;
console.log(x,y);
// 第二组代码
console.log(a,b);
var a = 9;
var b = 11;
// 第三组代码
console.log(t);
对比上面三组输出结果
第一组输出结果是: 5 7
没有异常
而第二组输出,按照我们的理解,会把声明提升到console.log()之前,那应该会输出9 11
但是输出结果并不是,而是undefined undefined
再看第三个输出,是报错,t is not defined
第二个输出组显然是a和b已经声明了,但是未定义,而t呢,则是没有声明
因此第二组代码在解释器中的情况实际上是这样子的:
var a;
var b;
console.log(a,b);
a = 9;
b = 11;
输出的结果,便是 undefined undefined
# 2.与函数相关的
我们先看一下这段代码的对比
// 第一组代码
console.log(a);
var a = 233;
a = function () {
console.log('233');
}
console.log(a);
//==============================//
// 第二组代码
console.log(b);
var b = 666;
function b () {
console.log('666');
}
console.log(b);
按照前面的了解,第一组代码中 var a将会被提前,因此第一个console.log(a)的输出应该是undefined
执行完了console.log(a)之后,a被赋值为233,然后又被赋值为一个函数
因此第二个console.log(a)的输出,则是函数里的内容
f a () {
console.log(233)
}
在第一组代码中,函数是通过赋值的方式定义的,因此不会被提前,而接下来我们看到第二组代码
在第二组代码之中,var b将会被提前,那么function b(){}会不会提前呢?
答案是会的,这里的函数b采用的是声明法,函数声明和变量声明都被提前,因此,第二组代码在解释器中顺序如下:
function b () {
console.log('666');
}
var b;
console.log(b);
b = 666;
console.log(b);
因此输出的内容是
f b () {
console.log(666)
}
666
需要注意的是,在函数声明和变量声明都提升的情况下,函数声明会在变量声明之前。
因此我们看到这组代码
console.log(c);
// 函数声明
function c () {
console.log('8080');
}
var c = 8080;
// 函数表达式
c = function () {
console.log('8080test');
}
console.log(c);
输出结果如下:
f c () {
console.log('8080');
}
f () {
console.log('8080test');
}
这里也引出了函数声明与函数表达式的区别
通过函数声明定义的函数,在整个作用域中无论前后都可以调用
但通过函数表达式定义的函数,需要在其赋值的位置之后才可以调用
顺带一提,有没有发现,函数声明的函数经过console.log()出来后,多了个c?应该说,通过函数表达式之后少了个c?
是因为 c = function () {} 赋值给c的是一个匿名函数,我们可以c = function xxx () {} 看看是一个怎么样的情况
# 3.let 与 const
let 与 const都必须先定义再使用,因此:
console.log(a);
var a = 233;
console.log(b);
let b = 666;
会发现,console.log(b)无法执行
再者,const必须在定义的时候就进行初始化,更不可能提前。
# 4.总结
总的来说,声明提前会带来一定的问题和影响,也容易造成一些不良的习惯。
在编写代码的时候应该注意在每个作用域开始前声明变量与函数,避免问题发生,也符合JavaScript的解析步骤,易于理解。
同时随着使用的技术不断更新,更多的采用ES6新增的,用于弥补var关键字一系列漏洞的,关键字 let 和 const,养成良好的编程习惯与风格。