函數聲明提升
假如有函數聲明如下:
func() //調用語句在聲明之前
function func () {
}
上例不會報錯,正是因爲 ‘函數聲明提升’,即將函數聲明提升到作用域頂部(注意是函數聲明,不包括函數表達式),相當於:
// 函數聲明提升
function func () {
}
func()
但如果是函數表達式:
func() //調用語句在聲明之前
var func = function() {
}
這會報錯,相當於 :
var func;
func()
//只是提升了聲明,但是賦值語句沒有
func = function() {
}
變量聲明提升
只有 var 聲明的變量纔有變量提升,let、const 沒有,變量賦值也沒有提升。函數聲明提升優先於變量提升,函數聲明會被變量賦值影響,但不會被變量聲明影響。
console.log(num)
var num = 10
console.log(func)
var func = function () {
}
上兩例均會打印出 'undefined',變量聲明提升會將變量聲明提升到作用域頂部,但只會提升聲明部分,不會提升賦值部分。
注意,因爲 javascript 沒有塊級作用域這個概念,所以聲明提升會放到全局域或者當前函數作用域的頂部。
示例
示例一
var foo = function(){
console.log(123)
}
function foo(){
console.log(456)
}
foo()
第一眼可能會以爲是打印 456,但是聲明提升之後是這樣的:
var foo; // 變量聲明提升
function foo(){ // 函數聲明提升
console.log(456)
}
foo = function(){ // 變量賦值依然保留在原來位置
console.log(123)
}
foo()
所以應該輸出 123。
示例二
var func = 10
console.log(func && typeof(func))
function func () {
}
-----
console.log(func && typeof(func))
function func () {
}
var func = 10
上兩例將分別輸出 ‘number’、'function',原因是 函數聲明提升優先於變量提升,函數聲明會被變量賦值影響,但不會被變量聲明影響,實際提升後結果如下:
function func () {
}
var func = 10
console.log(func && typeof(func))
-----
function func () {
}
var func
console.log(func && typeof(func))
func = 10
示例三
num = 10
function func () {
window.num = 5
console.log(num)
var num
console.log(window.num)
}
func()
上例將會分別打印出 'undefined'、'5',第一處爲局部變量,第二處爲全局變量,實際提升後結果如下:
function func () {
var num
window.num = 5
console.log(num)
console.log(window.num)
}
var num
num = 10
func()
參考
參考博客:https://www.cnblogs.com/jf-67/p/8036966.html
參考博客:https://blog.csdn.net/qq_33576343/article/details/81458133