提升问题
var
声明变量提升和函数提升
- 函数优先提升
- 函数提升后,变量提升,因为函数声明
foo
已经提升,所以变量提升的foo
会被忽略
- 函数提升后,变量提升,因为函数声明
foo();//2
var foo;
function foo() {
console.log(2);
}
- 函数重复声明的提升
- 与
var
声明不同,后面的函数声明会覆盖前面的函数声明
- 与
foo();//3
function foo() {
console.log(2);
}
function foo() {
console.log(3);
}
- 声明本身会被提升,赋值操作(包括函数表达式赋值)不会被提升,而是留在原来的位置
console.log(foo); //undefined
var foo = function () {
console.log(1);
};
看穿提升
- 首先判断并找出全局作用域和函数作用域(不用找块级作用域,因为只有var声明才会变量提升)。
- 把每一句用var声明的语句(等号左边)视为处于当前作用域的最上方,赋值操作留在原地。
- 注意var重复声明会忽略靠后的声明,而函数声明会被靠后的同名函数声明覆盖。
var
变量提升不受判断条件影响。- 现代浏览器不会对if里面的函数声明进行提升(允许在块级作用域声明函数),只有老版本IE会提升。
注意
var bar = 1;
function foo() {
console.log(bar);//undefined 从当前作用域开始查找变量web
if (false) {
var bar = 2;//var web; 在foo函数作用域被提升
}
}
foo();
var没有块级作用域,所以会提升到当前函数作用域的顶层
function foo() {
console.log(100);
}
(function () {
if (false) {
function foo() {
console.log(200);
}
}
// foo();//报错
console.log(foo);//undefined
})();
//相当于以下代码
(function () {
var foo; //undefined
if (false) {
function foo() {
console.log(200);
}
}
})();
允许在块级作用域内声明函数
这时,函数声明类似于var,会提升到当前作用域顶层
同时,函数声明会提升到块级作用域头部
应该避免在块级作用域声明函数,在需要的情况下,应该写成函数表达式形式,而不是函数声明形式