JavaScript 变量提升和函数提升,以及它们的优先级


一、变量提升

ES6 之前,函数没有块级作用域(一对{}即一个块级作用域),只有全局作用域和函数作用域。变量提升是指将变量申明提升到它所在的作用域的最开始部分。

例子:

console.log(foo) // undefined
var foo = '小花猫'
console.log(foo) // 小花猫

相当于:

var foo
console.log(foo)
foo = '小花猫'
console.log(foo)

二、函数提升

函数创建有两种方式:
1、函数申明形式;
2、函数字面量形式(即函数表达式)。【而只有函数声明形式才有函数提升】,还有一种是方式:函数构造法:var a = new Fun(),技术角度来讲也是一个字面量形式。

// 声明式
function foo() {
  // to do...
}

函数提升,相当于:

// 函数字面量
var foo = function () {
  // to do...
}

例子:

console.log(bar) // f bar() { console.log(123) }
console.log(bar()) // undefined
var bar = 456
function bar() {
  console.log(123) // 123
}
console.log(bar) // 456
bar = 789
console.log(bar) // 789
console.log(bar()) // bar is not a function

相当于:

// js执行步骤

// 函数提升,函数提升优先级高于变量提升
var bar = function () {
  console.log(123)
}
// 变量提升,变量提升不会覆盖(同名)函数提升,只有变量再次赋值时,才会被覆盖
var bar
console.log(bar)
console.log(bar())
// 变量赋值,覆盖同名函数字面量
bar = 456
console.log(bar)
// 再次赋值
bar = 789
console.log(bar)
console.log(bar())

结果:

// js执行结果

f bar() { console.log(123) }
123  // 执行bar()里的console.log
undefined // bar()的返回值,如果函数没有返回值,默认为:undefined
456
789
[typeError]:bar is not a function

三、优先级

函数提升优先级高于变量提升,且不会被同名变量声明时覆盖,但是会被变量赋值后覆盖

最后留个练习题,大家思考一下。

console.log(person)
console.log(fun)
var person = 'jack'
console.log(person)

function fun() {
  console.log(person)
  var person = 'tom'
  console.log(person)
}
fun()
console.log(person)

Author: Eric
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Eric !
  TOC