1. 程式人生 > >從一道面試題談js函式宣告

從一道面試題談js函式宣告

愛奇藝前端面試題有個題目如下:

a();
function a(){
    console.log('a');
}

b();
var b = function(){
    console.log('b');
}
那麼函式的執行結果是?

熟悉函式變數提升的同學很容易就想到答案是:a undefined。

不熟悉的童鞋們可以接著往下看~

JS關於函式的宣告,有一個很重要的特徵就是函式的變數提升。意思是在執行程式碼之前會先讀取函式的宣告。這就意味著可以把函式宣告放在呼叫它的語句後面。

sayHi();
function sayHi(){
    alert('hi');
}

這個例子不會丟擲錯誤,因為在程式碼執行前會被先去函式宣告。
第二種建立函式的方式是使用函式表示式。函式表示式有幾種不同的語法形式。下面是最常見的一種形式。

var functionName = function(arg0,arg1){
    //函式體
};

這種形式看起來好像是常規的變數賦值語句,即建立一個函式並將它賦值給變數functionName。這種情況下建立的函式叫做匿名函式,因為function關鍵字後面沒有識別符號。匿名函式的name屬性是空字串。(匿名函式有時候也叫拉姆達函式

函式表示式和其他表示式一樣,在使用前必須先賦值。以下程式碼會導致錯誤:

sayHi();
var sayHi = function(){
    alert('hi');
}

這也就是上面那道題輸出結果的原因。

另外,執行以下程式碼的結果可能會讓人意想不到。

//不要這樣做!
if(condition){
    function sayHi(){}
}
else{
    function sayHi(){}
}

表面上看,以上程式碼在condition為true時,使用一個sayHi定義,否則使用另一個。實際上,這在ECMScript中屬於無效的語法,JavaScript引擎會嘗試修正錯誤,將其轉化為合理的狀態。但問題是瀏覽器嘗試修正錯誤的做法並不一致。大多數瀏覽器會返回第二個宣告,忽略condition;FIrefox會在condition為true時返回第一個宣告。因此這種使用方式很危險,不應該出現在我們的程式碼中。
這種形式,JS引擎在預編譯的過程中會註冊方法到window物件下,就是window.sayHi。而不會顧及if else條件,導致重複的sayHi方法被註冊,在這種情況下是無效語法。
不過,如果是使用函式表示式,那就沒什麼問題了。

//可以這樣做
var sayHi;
if(condition){
    sayHi = function(){
        ....
    }
}
else{
    sayHi = function(){
        ....
    }
}

這個例子不會有什麼意外,不同的函式會根據condition被賦值給sayHi。

相關推薦

一道試題js函式宣告

愛奇藝前端面試題有個題目如下: a(); function a(){ console.log('a'); } b(); var b = function(){ console.log('b'); } 那麼函式的執行結果是? 熟悉函式變數

一道試題linux下fork的執行機制

今天一位朋友去一個不錯的外企面試linux開發職位,面試官出了一個如下的題目:     

一道試題看ES6箭頭函式

前幾天頭條面試碰到了這樣一道面試題,讓我寫出每行程式碼的執行結果: var f = x => x; f(1); //return 1 var f = x => {x}; f(1); //function(x)={x}; var f = x =

一道試題來認識java類加載時機與過程【轉】

包含 布局 hello 印象 大致 周期 default () itl 說明:本文的內容是看了《深入理解Java虛擬機:JVM高級特性與最佳實踐》後為加印象和理解,便記錄了重要的內容。 1 開門見山 以前曾經看到過一個java的面試題,當時覺得此題很簡單,可是自己

有關java類、對象初始化的話題,一道試題切入

() 深入理解java 補充 [] base sna 字體 都是 spa 最近在整理東西時,剛好碰到以前看的一道有關java類、對象初始化相關題目,覺得答案並不是非常好(記憶點比較差,不是很連貫)。加上剛好復習完類加載全過程的五個階段(加載-驗證-準備-解析-初始化),所以

一道試題徹底搞懂hashCode與equals的作用與區別及應當注意的細節

public class HashCodeTest { public static void main(String[] args) { Collection set = new HashSet(); Point p1 = new Point(1, 1); Point p2 = new Poin

一道試題來認識java類載入時機與過程

說明:本文的內容是看了《深入理解Java虛擬機器:JVM高階特性與最佳實踐》後為加印象和理解,便記錄了重要的內容。 1  開門見山 以前曾經看到過一個java的面試題,當時覺得此題很簡單,可是自己把程式碼執行起來,可是結果並不是自己想象的那樣。題目如下: class SingleTon {

Android多執行緒研究(4)——一道試題說起

有一道這樣的面試題:開啟一個子執行緒和主執行緒同時執行,子執行緒輸出10次後接著主執行緒輸出100次,如此反覆50次。先看下面程式碼:package com.maso.test; /** * * @author Administrator * 兩個執行緒,其中是一個

一道試題說說方法的引用傳遞和值傳遞

就是說有這麼一道面試題,題目如下: using System; public class Test1 { public static void Main() { int num = 0; Person p = new Pe

一道試題開始說起 列舉、動態代理的原理

本文已在我的公眾號hongyangAndroid原創釋出。 轉載請標明出處: 本文出自:漲鴻洋的部落格 前段時間在dota群,一哥們出去面試,回顧面試題的時候,說問到了列舉。 作為一名Android選手,談到列舉,那肯定是: An

一道試題深入瞭解java虛擬機器記憶體結構

記得剛大學畢業時,為了應付面試,瘋狂的在網上刷JAVA的面試題,很多都靠死記硬背。其中有道面試題,給我的印象非常之深刻,有個大廠的面試官,順著這道題目,一直往下問,問到java虛擬機器的知識,最後把我給問住了。 我當時的表情是這樣的: 後來我有機會面試別人了,也按照他的思路出面試題,很多已經工作了2年的程式設

一道試題簡單談談釋出訂閱和觀察者模式

今天的話題是javascript中常被提及的「釋出訂閱模式和觀察者模式」,提到這,我不由得想起了一次面試。記得在去年的一次求職面試過程中,面試官問我,“你在專案中是怎麼處理非父子元件之間的通訊的?”。我答道,“有用到vuex,有的場景也會用EventEmitter2”。面試官繼續問,“那你能手寫程式碼,實現一

Python之美[菜鳥到高手]--讀"一道試題看 HashMap 的儲存方式"的聯想

在 HashMap 中存放的一系列鍵值對,其中鍵為某個我們自定義的型別。放入 HashMap 後,我們在外部把某一個 key 的屬性進行更改,然後我們再用這個 key 從 HashMap 裡取出元素,這時候 HashMap 會返回什麼?如何面試者直接答“這要看自定義型別的ha

探索一道試題的多個解法:C++11 求 1 到 10 的階乘相加的結果

一、引言 最近,有個朋友出去面試(才畢業不到一年),裡面有一道很簡單的筆試題: 請你編寫程式碼,求 1 到 10 的階乘相加的結果 這是一道非常簡單的題目,我們稍微動一動頭腦,就能拿出下面的程式碼: #include <iostream

一道試題引發的數據庫行列轉換實踐

聚合函數 列數 index 所有 then 重復 一個 mysq 場景 問題場景 最近有個朋友去面試,問了我一道面試題。題目如下,在形如下面的數據庫表score中,找出每門成績(grade)都大於等於80分的學生姓名。 -------------------------

經典試題js繼承方式下

deep 今天 typeof extend fun col const 繼承 uber 上一篇講解了構造函數的繼承方式,今天來講非構造函數的繼承模式。 一、object()方法 json格式的發明人Douglas Crockford,提出了一個object()函數,可以做到

Java基礎中的一道試題

override ktr void ati star 打印 str @override ... 這個是我以前的一道面試題: public class MyThread extends Thread { @Override public void run() { tr

關於Java類加載雙親委派機制的思考(附一道試題

另類 app 類庫 .com 任務 發現 clas context 表示 預定義類加載器和雙親委派機制 JVM預定義的三種類型類加載器: 啟動(Bootstrap)類加載器:是用本地代碼實現的類裝入器,它負責將 <Java_Runtime_Home>/l

跟濤哥一起學嵌入式 第04集:一道試題,測出你的C語言功底

inux 臨時 新增 取數據 max 指針 code 個人主頁 ctu 大家好,我是濤哥,歡迎閱讀《跟濤哥一起學嵌入式》第04集,今天聊聊面試題。 嵌入式C語言面試題中,大家經常會看到宏定義的考題。比如:定義一個宏,求兩個數中的最大數。別小看這個考題,雖然簡單,但是它卻陷阱

一道試題的分析

com var 沒有 優先級 alt 面試題 http console 圖片 題目: console.log(a); var a=1; console.log(a); function a(){console.log(2);} console.log(a); var a=