關於我在360筆試中做到的一道毀三觀的題(函數與變量同名)

昨天在答360筆試的時候,遇到這樣一道毀三觀的題;

var a = 3;
function a(){};
console.log(type a);

看到這段代碼,你的第一反應是他應該輸出什麼!
  我當時毫不猶豫,內心堅定無比的選擇了function。這並不是因爲後面覆蓋前面的問題,而是我們之前在學習js預解析的時候,學過這樣一段話,函數與變量同名時,函數優先級更高!於是我謹記,那麼這道題中,最終生效的一定就是函數!
  我的助攻幫我運行了這段代碼,然後他告訴我應該選擇number!什麼!!我當時一臉驚恐加不屑,堅信他一定是哪裏敲錯了!於是我依然義無反顧的選了function;直到筆試結束之後,我自己運行了一下這段代碼……
  當控制檯打印的number出現在眼前時,我簡直一臉懵逼,頓時感覺三觀的顛覆了……下面我們就來講解一下它。
  注意,前面說到的我們我你平常學習的時候說,函數與變量同名時,函數優先級更高。注意!!這裏說的是,函數聲明與變量聲明同名時!函數 聲明!! 的優先級更高。我們都知道:變量和賦值語句一起書寫,在js引擎解析時,會將其拆成聲明和賦值2部分,聲明置頂,賦值保留在原來位置。也就是說,這種情況:

var a;
function a(){};
console.log(a);  //function a(){}

這時:
   1)函數聲明會置頂
   2)變量聲明也會置頂
   3)函數聲明比變量聲明更置頂(可理解爲優先級高)
所以,此時的x是一個函數。
然而,這種情況:

var a = 3;
function a(){};
console.log(a);  //3

同一個標識符的情況下,變量聲明與函數聲明都會提升;函數聲明會覆蓋變量聲明,但不會覆蓋變量賦值,即:如果聲明變量的同時初始化或賦值那麼變量優先級高於函數。你可以理解爲,開始的聲明函數確實優先於變量,覆蓋了變量。但是在後面代碼執行到賦值語句時,a再次被賦值爲數字。相當於以下代碼:

function a(){};
a=3;
console.log(a);//3
console.log(typeof a);//number

你可以試試,就算聲明爲函數,賦值爲數字,也會變成number。

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