一 什么是提升?
变量和函数声明从它们在代码中出现的位置被“移动”到了最上面的过程,叫做提升
二 提升规则
结合编译原理:
Step1编译:声明变量 / 函数 ; 变量提升;作用域关联
Step2执行:赋值
var a = 2; //有两个独立的声明 //Step1: 编译,变量提升,作用域关联 var a; //Step2:执行,赋值 a = 2;
- 只有声明本身会被提升,而赋值或者其他运行逻辑会留着原地
foo();
function foo() {
console.log(a); //undefined
var a = 2;
}
//函数提升后、作用域内变量提升
function foo() {
var a;
console.log(a); //undefined
a = 2;
}
foo();
- 函数声明会被提升,但是函数表达式不会被提升
区别函数声明和表达式的方法:看function关键字出现在整个声明中的位置/它们的名称标识符将会绑定在何处
如果function是声明中的第一个词,那么就是一个函数声明,否则就是一个函数表达式
(function foo() { ... }) 作为函数表达式,意味着foo只能在 ...所代表的位置中被访问, 外部作用域则不行
foo(); // TypeError
var foo = function() { ... } //函数表达式不会提升
- 函数声明和变量声明都会被提升 -> 函数声明会首先被提升,然后才是变量 -> 多个同名的函数声明会进行覆盖
foo();
var foo;
function foo() {
console.log(1);
}
foo = function() {
console.log(2);
}
function foo() {
console.log(3);
}
//函数+变量提升后
function foo() {
console.log(1);
}
function foo() {
console.log(3);
}
var foo;
foo();//3
foo = function() {
console.log(2);
}
- 一个普通块内部的函数声明通常会被提升到所在作用域的顶部