JavaScript 聲明提升

函數聲明提升

假如有函數聲明如下:

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章