?? 前言
- 我們都知道在
JavaScript中同一個作用域內的變數都屬于這個區域,在別的作用域是獲取不到這個變數的, - 但是在同一個作用域內,其中變數的宣告的先后順序和位置其實是有奇特的關系的,而這個奇特的現象就是
變數提升,
🙇?♂? 什么是提升
-
想要搞懂提升只需要了解以下
四個方面即可,- 提升是什么現象
- 變數提升
- 函式提升
- 變數和函式的提升優先級
提升是什么現象
- 我們都知道
JavaScript是單執行緒的語言,一個任務結束才會進行下一個任務,這樣大家都默認認為執行會從上到下一條一條代碼去執行,這句話是對的但又不完全對,有一種情況會有特殊, - 我們觀察以下代碼,
console.log(text);
- 很明顯我們沒有宣告
text它是會報錯的,這是我們都知道的,如果是這樣呢?
console.log(text);
var text=828;
- 可能你會認為
text是在列印后宣告的,所以他還是會報錯,但實際上他沒有報錯,列印了一個undefined, - 再來看看下面一道經典面試題,
text=828;
var text;
console.log(text);
- 有很多人會覺得說宣告了
text之后沒有賦值,所以他會列印一個undefined,但實際上真正的列印結果是828,這又是為什么呢?
變數提升
- 當我們簡單的輸入一行代碼
var text=828;的時候如果我們不了解變數提升肯定會認為他只是簡簡單單將828賦值給了text這一個宣告,但實際上JavaScript做了兩步操作,分別是var text宣告,然后是text =828賦值, - 當編譯器在給
JavaScript編譯時會有兩個階段分別是編譯階段和執行階段,而編譯階段其中有做的處理是先找到同一個作用域中所有需要宣告的變數,先將其宣告(例如:var text)然后才到代碼的執行階段等待執行(例如:text =828), - 這也是為什么
var text=828會將他分成兩步操作的原因,說白了就是變數和函式的所有宣告都會在被執行前處理, - 而這個提前處理的程序我們就可以稱為
提升,我們再看回之前那個面試題,
text=828;
var text;
console.log(text);
- 由于變數提升所以其實它真正的順序是這樣的:
var text;
text=828;
console.log(text);
- 你可以認為是有關于
var宣告的變數都會提前,而賦值等操作都會停留在原地,這就是我們所說的變數提升,
函式提升
- 我們平時在撰寫代碼時也經常會發現在同一個作用域中只要我們宣告了函式,不管是在哪個位置都可以執行此函式,
addIce();
function addIce(){
console.log('加冰塊');
}
- 如上的代碼其實我們經常看到,這樣是沒有問題的,為什么在使用
addIce()之前并沒有宣告該函式卻不會報錯呢?這是因為函式宣告也有提升,它可以被理解為以下的形式:
function addIce(){
console.log('加冰塊');
}
addIce();
- 所以不只是變數可以提升,函式宣告在同一個作用域中也會提升,值得注意的是函式運算式是不會被提升的,我們來看下面的例子,
addIce();
var addIce=function(){
console.log('加冰塊');
}
- 這樣的代碼是會報錯的
addIce is not a function - 了解了變數提升和函式提升后我們其實可以很輕松就看出上面的問題所在了,
var addIce會被提升到最上面,他可以被理解為以下的形式:
var addIce;
addIce();
addIce=function(){
console.log('加冰塊');
}
- 在
addIce被賦值前就被使用了理所當然是會報錯的,
變數提升和函式提升的優先級
- 我們現在都知道了變數和函式都會提升,那么假設有這一種情況:
addIce();
console.log(addIce);
var addIce;
function addIce(){
console.log('加冰塊');
}
- 在以上的代碼執行后列印了一個
addIce()和加冰塊,以上的代碼可以理解為以下的形式:
function addIce(){
console.log('加冰塊');
}
addIce();
console.log(addIce);
- 我們可以看到當重復宣告了一個
addIce后,var addIce直接就會被忽略了,雖然函式宣告和變數宣告都會提升,但是是函式會首先提升然后才到變數,雖然這種情況在日常中基本上不會出現也最好不要出現,但是還是得了解一下,
👋 寫在最后
- 由于提升這種情況,意味著在同一個作用域中無論是變數宣告還是函式宣告在什么地方都會在代碼被執行前先處理,也就是所謂的變數提升和函式提升,在兩者都存在時會優先提升函式宣告,
- 更加值得一提的是在變數提升中,由于
letconst的出現,這兩個宣告的變數都不會變數提升,只有var會, - 如果您覺得這篇文章有幫助到您的的話不妨🍉關注+點贊+收藏+評論+轉發🍉支持一下喲~~😛
- 更多前端資訊知識可以關注公眾號:『前端快快跑』
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/299195.html
標籤:其他
上一篇:JavaScript小面試~什么是深拷貝,什么是淺拷貝,深拷貝和淺拷貝的區別,如何實作深拷貝
下一篇:Node.js第一天
