一、变量提升
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)