溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

web前端高頻面試題實例代碼分析

發(fā)布時間:2023-02-28 09:43:49 來源:億速云 閱讀:129 作者:iii 欄目:web開發(fā)

本篇內(nèi)容介紹了“web前端高頻面試題實例代碼分析”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

面試官:請你談?wù)凧S的this指向問題

我:呃~,我們知道this中有個準則就是誰調(diào)用就指向誰,這句話潛移默化的會導(dǎo)致我們出現(xiàn)一些誤區(qū),現(xiàn)將可能會出錯的情況總結(jié)如下,并付出代碼:

1)我們要知道在全局的時候去得到這個this的話,this都會指向windows,因為我們在全局的情況下使用的東西都會被掛載到window上。

<script>
    console.log(this) // 指向window
    function a(){
        console.log(this)
    }
    a() // 相當于 window.a(),指向的依舊是 window
</script>

2)我要知道this的指向是會指向上一個調(diào)用者的,代碼如下:

看完了代碼,我們知道雖然本質(zhì)上是由于a才調(diào)用了d函數(shù),但是中間還是有一層是c調(diào)用了d函數(shù),所以this指向上一級會有一個就近原則的,這點很重要?。?!

<script>
    var a = {
        b:10,
        c:{
            b:12,
            d:function(){
                console.log(this)
            }
        }
    }
    a.c.d() // {b: 12, d: ?}
</script>

3)我們要知道箭頭函數(shù)是沒有作用域的,也就是說是沒有自己的this,它的this永遠向的是上一級的this,下面給出一道某大廠的面試題,大家可以猜一下最后的打印結(jié)果是什么?

假設(shè)你已經(jīng)仔細的看完了這道面試題,相信你心中已經(jīng)有了答案是66了,為什么呢?,要知道箭頭函數(shù)是沒有自己的this的,所以需要其去上一級去尋找this,而上一級處于全局作用域,所以打印的便是全局已經(jīng)掛載的id數(shù)66。

<script>
    var id = 66
    function a(){
        setTimeout(()=>{
            console.log(this.id)
        },500)
    }
    a({id:22}) // 猜猜結(jié)果是什么?
</script>

那我們如何改變this的指向,去控制this指向我們想要的結(jié)果呢?給出如下三種方法:

<script>
    var id = 66
    function a(){
        setTimeout(()=>{
            console.log(this.id || this)
        },500)
    }
    // call => {} 改變之后并執(zhí)行一次
    a.call({id:22}) // 打印22 

    // apply => [] 改變之后并執(zhí)行一次
    a.apply([12]) // 打印 [12]

    // bind() 不調(diào)用,只改變this指向
    a.bind(a(id=32)) // 32
</script>

面試官:說一說call apply bind的作用和區(qū)別?

我:呃~,好的,總結(jié)如下:

call apply bind三個方法都可以用來改變函數(shù)的this指向,具體區(qū)別如下:

1)fn.call (newThis,params) call函數(shù)的第一個參數(shù)是this的新指向,后面依次傳入函數(shù)fn要用到的參數(shù)。會立即執(zhí)行fn函數(shù)。

2)fn.apply (newThis,paramsArr) apply函數(shù)的第一個參數(shù)是this的新指向,第二個參數(shù)是fn要用到的參數(shù)數(shù)組,會立即執(zhí)行fn函數(shù)。

3)fn.bind (newThis,params) bind函數(shù)的第一個參數(shù)是this的新指向,后面的參數(shù)可以直接傳遞,也可以按數(shù)組的形式傳入。  不會立即執(zhí)行fn函數(shù),且只能改變一次fn函數(shù)的指向,后續(xù)再用bind更改無效。返回的是已經(jīng)更改this指向的新fn

面試官:請你談?wù)剬κ录械睦斫?/strong>

我:呃~,好的,事件委托就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。說白了就是將還沒有出現(xiàn)的事件,掛載到已經(jīng)出現(xiàn)的事件上。整出代碼如下:

<body>
<ul id="ul">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>
<button id="btn">點我添加一個li</button>
<script>
    // 事件委托
    let ul = document.getElementById("ul")
    ul.addEventListener('click',(event)=>{
        console.log(event)
        event = event || window.event
        let target = event.target
        if(target.nodeName == 'LI'){
            alert(target.innerHTML)
        }
    })

    let btn = document.getElementById('btn')
    btn.addEventListener('click',()=>{
        let li = document.createElement('li')
        li.textContent = ul.children.length
        ul.appendChild(li)
    })
</script>
</body>

web前端高頻面試題實例代碼分析

面試官:說一說promise是什么與使用方法?

我:呃~,好的,Promise是ES6提供的一個構(gòu)造函數(shù),可以使用Promise構(gòu)造函數(shù)new一個實例,Promise構(gòu)造函數(shù)接收一個函數(shù)作為參數(shù),這個函數(shù)有兩個參數(shù),分別是兩個函數(shù) resolvereject,resolve將Promise的狀態(tài)由等待變?yōu)槌晒Γ瑢惒讲僮鞯慕Y(jié)果作為參數(shù)傳遞過去;reject則將狀態(tài)由等待轉(zhuǎn)變?yōu)槭。诋惒讲僮魇r調(diào)用,將異步操作報出的錯誤作為參數(shù)傳遞過去。實例創(chuàng)建完成后,可以使用then方法分別指定成功或失敗的回調(diào)函數(shù),也可以使用catch捕獲失敗,thencatch最終返回的也是一個Promise,所以可以鏈式調(diào)用。

Promise的作用

Promise是異步微任務(wù),解決了異步多層嵌套回調(diào)的問題,讓代碼的可讀性更高,更容易維護 Promise使用

Promise的特點

1)對象的狀態(tài)不受外界影響

2)一旦狀態(tài)改變,就不會再變,任何時候都可以得到這個結(jié)果

3)resolve 方法的參數(shù)是then中回調(diào)函數(shù)的參數(shù),reject 方法中的參數(shù)是catch中的參數(shù)

4)then 方法和 catch方法 只要不報錯,返回的都是一個fullfilled狀態(tài)的promise

應(yīng)用場景

解決地獄回調(diào)問題

具體使用方法,參考我之前的文章:一文搞懂JS中的Promise

面試官:說一說跨域是什么?如何解決跨域問題?

我:呃,好的,總結(jié)內(nèi)容如下:

什么是跨域

當前頁面中的某個接口請求的地址和當前頁面的地址如果協(xié)議、域名、端口其中有一項不同,就說該接口跨域了。
跨域限制的原因:

瀏覽器為了保證網(wǎng)頁的安全,出的同源協(xié)議策略。

跨域解決方案

cors

目前最常用的一種解決辦法,通過設(shè)置后端允許跨域?qū)崿F(xiàn)。
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader("Access-Control-Allow-Methods", "GET, PUT, OPTIONS, POST");

node中間件、nginx反向代理

跨域限制的時候瀏覽器不能跨域訪問服務(wù)器,node中間件和nginx反向代理,都是讓請求發(fā)給代理服務(wù)器,靜態(tài)頁面面和代理服務(wù)器是同源的,然后代理服務(wù)器再向后端服務(wù)器發(fā)請求,服務(wù)器和服務(wù)器之間不存在同源限制。
JSONP

利用的原理是script標簽可以跨域請求資源,將回調(diào)函數(shù)作為參數(shù)拼接在url中。后端收到請求,調(diào)用該回調(diào)函數(shù),并將數(shù)據(jù)作為參數(shù)返回去,注意設(shè)置響應(yīng)頭返回文檔類型,應(yīng)該設(shè)置成javascript。

面試官:說一說JavaScript有幾種方法判斷變量的類型?

我:呃,好的,JavaScript有4種方法判斷變量的類型,總結(jié)如下:

typeof

常用于判斷基本數(shù)據(jù)類型,對于引用數(shù)據(jù)類型除了function返回’function‘,其余全部返回’object'。

instanceof

主要用于區(qū)分引用數(shù)據(jù)類型,檢測方法是檢測的類型在當前實例的原型鏈上,用其檢測出來的結(jié)果都是true

Object.prototype.toString.call()(對象原型鏈判斷方法):

適用于所有類型的判斷檢測,檢測方法是Object.prototype.toString.call(數(shù)據(jù)) 返回的是該數(shù)據(jù)類型的字符串。

constructor(用于引用數(shù)據(jù)類型):

用于檢測引用數(shù)據(jù)類型,檢測方法是獲取實例的構(gòu)造函數(shù)判斷和某個類是否相同,如果相同就說明該數(shù)據(jù)是符合那個數(shù)據(jù)類型的,這種方法不會把原型鏈上的其他類也加入進來,避免了原型鏈的干擾。

面試官:說一說JS實現(xiàn)異步的方法?

我:呃~,好的,所有異步任務(wù)都是在同步任務(wù)執(zhí)行結(jié)束之后,從任務(wù)隊列中依次取出執(zhí)行。常見的實現(xiàn)異步的方式如下:

回調(diào)函數(shù)、事件監(jiān)聽、setTimeout(定時器)、Promise、async/await,generator生成器

面試官:說一說數(shù)組去重都有哪些方法?

我:呃~,數(shù)組去重的方法有很多,舉幾個例子并簡單的加以說明,如下:

利用對象屬性key排除重復(fù)項

遍歷數(shù)組,每次判斷對象中是否存在該屬性,不存在就存儲在新數(shù)組中,并且把數(shù)組元素作為key,設(shè)置一個值,存儲在對象中,最后返回新數(shù)組。

利用Set類型數(shù)據(jù)無重復(fù)項

new 一個 Set,參數(shù)為需要去重的數(shù)組,Set 會自動刪除重復(fù)的元素,再將 Set 轉(zhuǎn)為數(shù)組返回。

filter+indexof 去重

利用 Array 自帶的 filter 方法,返回 arr.indexOf(num) 等于 index 的num。

reduce +includes去重

利用reduce遍歷和傳入一個空數(shù)組作為去重后的新數(shù)組,然后內(nèi)部判斷新數(shù)組中是否存在當前遍歷的元素,不存在就插入到新數(shù)組中。

面試官:說一說es6中箭頭函數(shù)?

我:呃~,好的,箭頭函數(shù)相當于匿名函數(shù),簡化了函數(shù)定義。箭頭函數(shù)有兩種寫法,當函數(shù)體是單條語句的時候可以省略{}和return。另一種是包含多條語句,不可以省略{}和return。 箭頭函數(shù)最大的特點就是沒有this,所以this是從外部獲取,就是繼承外部的執(zhí)行上下文中的this,由于沒有this關(guān)鍵字所以箭頭函數(shù)也不能作為構(gòu)造函數(shù)。

箭頭函數(shù)比普通函數(shù)的定義寫法更加簡潔明了和快捷。但是兩者又有區(qū)別:箭頭函數(shù)沒有原型prototype和super,所以無法創(chuàng)建this,其this是通過繼承外部函數(shù)環(huán)境中的變量獲取的,所以call、bind、apply都無法改變其this的指向;在找不到最外層的普通函數(shù)時,其this一般指向window;箭頭函數(shù)不能使用new;箭頭函數(shù)沒有arguments;也不能作為generator函數(shù),不能使用yield命令;箭頭函數(shù)不能用于對象域和回調(diào)函數(shù)動態(tài)this中,一般用在內(nèi)部沒有this引用。

面試官:說一說JS變量提升?

我:呃~,好的,變量提升是指JS的變量和函數(shù)聲明會在代碼編譯期,提升到代碼的最前面。 變量提升成立的前提是使用Var關(guān)鍵字進行聲明的變量,并且變量提升的時候只有聲明被提升,賦值并不會被提升,同時函數(shù)的聲明提升會比變量的提升優(yōu)先。 變量提升的結(jié)果,可以在變量初始化之前訪問該變量,返回的是undefined。在函數(shù)聲明前可以調(diào)用該函數(shù)。

使用let和const聲明的變量是創(chuàng)建提升,形成暫時性死區(qū),在初始化之前訪問let和const創(chuàng)建的變量會報錯。

“web前端高頻面試題實例代碼分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI