4.提升
4.1 先有鸡还是先有蛋
根据声明的位置和方式将变量分配给作用域。
- a = 2;
- var a;
- console.log(a); // 2
- console.log(a); // undefined
- var a = 2;
4.2 编译器
复习:编译的第一阶段是:找到所有的声明,并用合适的作用域将它们关联起来。
即:包括变量和函数在内的所有声明都会在任何代码执行前首先被处理。
var a = 2;
第一步:定义声明在编译阶段
第二步:赋值声明在执行阶段
总结:先有蛋(声明) 后有鸡(赋值)
每块作用域都会进行提升操作。
4.3 函数
函数声明会被提升,函数表达式不会被提升。
即使是具名函数的函数表达式,名称标识符在赋值之前也无法在所在作用域中使用。
- foo(); // TypeError
- bar(); // ReferenceError
- var foo = function bar(){
- //...
- }
后面的函数声明可以覆盖前面的。
- foo(); //3
- function foo(){
- console.log(1);
- }
- var foo = function(){
- console.log(2);
- }
- function foo(){
- console.log(3);
- }
一个普通快内部的函数声明会被提升到自身作用域顶部,
不会被条件语句控制。
- foo();// b
- var a = true;
- if(a){
- function foo(){
- console.log('a');
- }
- }else{
- function foo(){
- console.log('b');
- }
- }