函数提升
函数声明时,会将声明提升到当前作用域的顶部
{
fun()
function fun(){
console.log(123) // 123
}
}
上面的代码在声明fun前就调用了fun,结果是正常执行,输出123,说明了函数声明会被提升
创建函数还有两种方式
1、通过构造函数
2、函数表达式
这两种方式使用时是将生成的函数赋值给一个变量,若该变量是用var声明的,则存在的是变量提升
函数表达式
//var 变量提升
{
fun() // TypeError: fun is not a function
var fun = function(){
console.log(123)
}
}
//let 不存在变量提升,浏览器环境下直接报变量未定义的错误
//node环境下,报错:ReferenceError: Cannot access 'fun' before initialization
//不同环境下的报错信心不一致
{
fun() // Uncaught ReferenceError: fun is not defined
let fun = function(){ //
console.log(123)
}
}
构造函数
{
fun() // TypeError: fun is not a function
var fun = new Function(console.log(123))
}
{
fun() // Uncaught ReferenceError: fun is not defined
let fun = Function(console.log(123))
}
结论:所以只有函数声明才会存在函数提升
变量提升
用var声明的变量会被提升到当前作用域的顶部
{
console.log(a) // undefined
var a = 123
}
函数提升和变量提升的优先级
console.log(a) // ƒ a(){}
var a = 123
function a(){}
编译后:
var a
function a(){} //覆盖a变量的undefined值
console.log(a) // ƒ a(){}
a = 123
结论:存在同名的var变量和函数声明时,变量提升会将变量声明提升到函数声明之前,同名的函数声明会覆盖变量,所以函数声明提升的优先级要高于var的变量声明提升
console.log(b) // ƒ b(){}
b() // 123
var b = 123
b() // TypeError: fun is not a function
function b(){
console.log(123)
}
编译后:
//变量提升
var b
//函数声明被提升
function b(){
console.log(123)
}
console.log(b) // ƒ b(){}
b() // 123
b = 123 //覆盖函数声明
b() // TypeError: fun is not a function
结论:因为函数声明被提升了,在同名的var变量被赋值的时候,会覆盖函数声明,变量赋值的优先级高于函数声明
结论
1. 变量提升会将变量声明提升到函数声明之前
2. 函数提升优先级高于变量提升
3. 变量赋值优先级高于函数提升
自测环节
console.log(a)
a()
var a = 1
function a(){
console.log(123)
}
console.log(a)
a = 2
a()