当你看到var a=2;时,可能会认为这是一个声明。但js实际上回将其看成两个声明:var a;和a=2;。第一个定义声明是在编译阶段进行的。第二个赋值声明会被留在原地等待执行阶段。
a=2; var a; console.log(a);//2
console.log(a);//undefined var a=2;
每个作用域都会进行提升操作。函数内部也会对变量进行提升(显然并不是提升到了整个程序的最上方,在函数内部的最上方)。
foo(); function(){ console.log(a);//undefined var a=2; } 等同于 function foo(){ var a; console.log(a);//undefined a=2; } foo();
可以看到,函数声明会被提升,但是函数表达式却不会被提升
函数声明和变量声明都会被提升。但是函数会首先被提升,然后才是变量。
foo();//1 var foo; function foo(){ console.log(1); } foo=function(){ console.log(2); }; 这段代码会被引擎理解为如下形式: function foo(){ console.log(1); } foo();//1 foo=function(){ console.log(2); };
var foo尽管出现在function foo()的声明之前,但它是重复的声明(因此被忽略了),因为函数声明会被提升到普通变量之前。
尽管重复的var声明会被忽略掉,但出现在后面的函数声明还是可以覆盖前面的。
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");} }