天天看點

前端常見面試題

題目要求很明确,要求最終輸出“searchText1”,并且在500ms後輸出“searchText7”,很明顯就是關于同一個函數在短時間内重複調用,如何限制其調用頻率的功能實作。

首先,拿到題目後我們先運作一下,運作後報錯,顯示“triggerScroll is not a function”;由于題目中throttle函數沒有傳回值,是以triggerScroll接收到的throttle傳回值為undefined,首先我們要在throttle函數中return一個函數,也就是throttle在調用時傳進去的第一個參數。

這時再運作,控制台列印“searchText1-6”;這時我們隻需要把防抖的通用模闆套進去就可以實作了,我這裡用的防抖,其實使用節流函數也是可以實作的,原理相同,我這裡就不展示了,完整代碼如下:

另附上防抖和節流的通用模闆:

最終輸出結果為“1 1 2 0”。這一題也會涉及到閉包,作用域等知識點。

首先我們需要了解js運作流程:首先進行文法解析;先通篇的檢查js文法,若文法有誤,則報錯。其實進行預編譯;即發生在代碼執行之前,為代碼的執行做的準備工作,一般表現于變量提升,即把變量的聲明提前,但是指派還是在響應位置指派,再者就是把整個函數聲明提前。最後js運作流程進入最後一步即解析執行。

搞懂js運作流程再區分作用域,即全局作用域和函數作用域,全局作用域顧名思義就是全局聲明的變量或函數等。函數作用域也就是函數内部的作用域,在函數内部中聲明的變量或函數是不會傳到全局作用域的。

搞懂這兩個概念這一題就能夠迎刃而解了,首先全局聲明了一個變量i并指派為0,在聲明一個fun接受fn執行後的傳回值,是以fn會執行一次,局部變量i在fn函數中重新聲明,變量提升,這時函數fn中使用的i都為函數作用域中聲明的i,并且重新指派為1,輸出結果1。這裡不會影響到全局變量i的值。再觀望整體代碼,全局變量i未被重新指派,是以最後一行i輸出為0.

再往下走,fu函數的傳回值也是一個函數,是以fun接收到的是一個函數,fun函數被執行兩次,注意到在fn函數中,i被重新聲明過,是以這裡的傳回值函數即fun函數的作用域為局部作用域,使用的變量i為局部變量,即再fn函數中聲明的i,是以輸出1。輸出之後i自增1,即 i = i+1,局部作用域i的值在fun函數弟一次執行後變為2,再次執行後,輸出i為2。

這一題主要涉及到值類型和引用類型的存儲方式,即堆記憶體和棧記憶體。

首先題目中聲明了一個函數fn和一個對象xt,調用fn函數,并把xt傳入函數。這是第二行的obj和xt都為引用類型,新增了obj的屬性name值也為name。由于此時obj和xt指向的同一片記憶體空間,是以xt也會新增name屬性,并設定值為name。故最後一個輸出name。

在第三行中可以看到obj被重新指派,即重新開辟了一片記憶體空間,這時obj依然為新增name屬性而不是修改name屬性,并将name屬性設定為newName,是以這是obj新增的屬性不會影響到對象xt的屬性。

這一題主要是考察異步代碼和同步代碼執行的先後順序以及js任務隊列。

首先可以看到題目中有兩個循環體,兩個循環體中分别有兩個延時200ms的延時器。做題之前我們應該先了解到JavaScript對于同步代碼和異步代碼的處理方式,js會先執行同步代碼,遇到異步代碼(例:延時器、計時器、Promise等)會先放置任務隊列,等待觸發條件依次執行。這個概念了解清楚後這題就能夠迎刃而解了。

首先兩個循環體為同步代碼,會先執行。此時第一個循環體會将循環出的五個延時器放置任務隊列,等待200ms後執行。第二個循環體也是如此,是以輸出為“0 1 2 3 4  0 1 2 3 4”。

此題主要是考察對于同步異步,以及宏任務和微任務的了解。

此題最終輸出結果為“2 3 5 4 1”;

解答此題我們需要先了解到Promise的特性。Promise是異步程式設計的一種解決方案,是解決恐怖回調/回調噩夢的一種方案,其就相當于一個容器,裡面儲存着某個未來才會結束的事件(通常是一個異步操作)的結果。

建立promise對象,function就相當于容器,用于存放異步代碼(不僅限于異步,同步也可以),此函數在頁面加載時會正常執行,同步代碼會進入主線程執行,異步代碼會進入任務隊列,未來才會得到結果。并且Promise有三種狀态,進行時(pending預設值),已成功(fulfilled/resolved),已失敗(rejected)一旦狀态改變,就不會再變,任何時候都可以得到這個結果,成功後會調用.then()方法,then方法接受兩個參數,皆為回調函數,第一個函數promise狀态變為已成功時觸發的,第二個函數promise狀态變為已失敗時觸發。

了解了Promise後,我們還需要搞清楚宏任務和微任務的概念。在上面我們提到過,js會見異步代碼放置任務隊列,宏任務是由宿主(Node、浏覽器)發起的,常見的就是計時器和延時器;而微任務是由js引擎發起的,常見的就時Promise;執行順序為微任務先執行,宏任務後執行。

這時我們就可以來解答這個題目了,首先遇到延時器,為宏任務,放入任務隊列,其實遇到promise,先執行promise的同步代碼,輸出2,再進入循環,第一次進入循環index被重新指派為9999,并且将promise的狀态改為已成功,再往下走輸出3;

此時promise狀态為已成功,觸發then方法的第一個函數,但是promise響應為異步響應。并且為微任務,放置任務隊列,排在宏任務之前。再往下走就輸出5。

此時同步代碼執行完畢,開始執行異步代碼,先執行微任務,輸出4,在執行延時器代碼。輸出5。

好啦。以上就是小譚今天分享的内容啦,也歡迎各位一起來讨論技術呀!文章中有不足的地方小譚也歡迎各位指正探讨,不勝感激!

繼續閱讀