变量提升和函数提升是JS中最基本的知识,需要牢牢地掌握,用下面的例子简单讲一下变量提升和函数提升。
例子一
(function () {
console.log(a);
var a = 1;
function a() {
console.log('function a called');
}
console.log(a);
})();
// 先输出:function a called
// 后输出:1
这里输出的是名为a的函数,为什么是函数而不是undefined呢?这里需要记住这样一句话:
函数提升优先级高于变量提升,且不会被同名变量声明时覆盖,但是会被变量赋值后覆盖。
这说明了函数是会先于变量进行提升的,所以会先声明函数a,然后再去声明变量a,但是声明的时候变量a的undefined对函数a是无效的,它无法覆盖,所以a依旧是function a。然后,当代码执行到a = 1的时候,就是正常的赋值语句,a会被覆盖为1。
注意:变量提升(仅限于用var声明的变量)和函数提升只作用于全局作用域和函数作用域中,ES6引入的let和const已经提出必须先声明才可以进行调用,否则会报错。
例子二
(function () {
if (false) { //为true的时候会怎么样?
function a() { console.log("this is function a") }
}
console.log(a);// 输出: undefined
} ())
这里是一个立即执行函数里面有一个条件判断语句且为false里面包含了函数a的声明,这时候要怎么理解呢?
- 当条件语句为true:则声明函数a,且a会被提升到匿名函数作用域中进行声明。
- 当条件语句为false:函数声明会转为函数表达式,即function a() {} => var a = function() {},a变量会有变量提升。
综上,false的时候function a进行了变量a的提升,确没能进行赋值,所以输出为undefined。