a = 2
var a ;
console.log(a) // 2
 
 ------------------

console.log(a) // undefined
 var a  = 2

上述两种不同的结果,其实就是在声明变量时,编译器做了一个提升。

  • 变量和函数在内的所有声明都会在任何代码被执行前 首先被处理 (var会变量提升,let,const不会)
  • var a =2 其实被js视为2个声明,var a 和 a =2
  • 第一个定义声明时在编译阶段执行的,第二个赋值是会被留在原地等待执行阶段
  • var a 会被提到作用域最顶端,先令a为undefined,然后a = 2 再赋值。

所以上面的2段代码可以理解为:

var a ;
a =2 
console.log(a) //2

------------------

var a 
console.log(a) // undefined
a =2

函数提升

  • 函数声明会被提升,而函数表达式则不会被提升
foo() // TypeError
var foo = function bar (){...}
  • 这里报的的是类型错误,而不是引用错误
  • 函数表达式不会被提升,所以上面代码可以理解为
var foo ; // undefined
foo() // 调用foo方法,而foo是undefined,所以报TypeError
foo = function bar(){..} 
  • 即使具名的函数表达式,名称标识符在赋值之前也无法在所在的作用域中被提升使用

函数优先

  • 毕竟是“一等公民” 一等公民可以作为函数参数,可以作为函数返回值,也可以赋值给变量
  • 函数会被首先提升,然后才是变量
foo()  // 1 函数优先被提升
var foo

function foo(){
console.log(1)
}
foo = function(){
console.log(2)
}
  • 重复的var声明会被忽略,但是出现在后面的函数声明还是可以覆盖前面的
  • 尽量避免在块内部声明函数

爬。