2019 前端面試押題卷(1)【高級】

1、選擇題 (5道 * 5)

1. 表達式 [0, 1, 2].map(parseInt) 的結果爲?

A. [0, 1, 2]html

B. [0, 1, NaN]ajax

C. [NaN, NaN, NaN]編程

D. [0, NaN, NaN]json


2. 標籤中設置圖片加載失敗的替換文本的屬性名稱是?

A. alt跨域

B. title數組

C. textpromise

D. content瀏覽器


3. 如下哪個 CSS 樣式會建立塊格式化上下文(BFC)?

A. float: none;bash

B. position: relative;服務器

C. display: inline-flex;

D. overflow: visible;


4. 如下 CSS代碼中設置的 標籤的最終顏色是?

div { color: red; }

.test { color: green; }

[class="test"] { color: blue; }

html div { color: yellow; }

A. red

B. green

C. blue

D. yellow


5. 在跨域資源共享(CORS)中,瀏覽器會使用什麼方法發起預檢請求?

A. HEAD

B. OPTIONS

C. GET

D. POST


2、簡答題 (3道 * 15)

1. 考查JS運行時的理解,下列代碼的運行結果是?


if (!("a" in window)) {
    var a = 1;
}
alert(a);複製代碼


2. 理解宏任務和微任務,在Node.js運行環境中輸出結果是?

process.nextTick(() => {
  console.log('nextTick')
})
Promise.resolve()
  .then(() => {
    console.log('then')
  })
setImmediate(() => {
  console.log('setImmediate')
})
console.log('end')複製代碼


3. 防抖函數的做用是什麼?請實現一個防抖函數


3、編程題 (2道 * 15)

1. 使用 Promise封裝一個 ajax


var getJSON = function (url) {
    var promise = new Promise(function (resolve, reject) {
        var client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();

        function handler() {
            if (this.readyState !== 4) {
                return;
            }
            if (this.status === 200) {
                resolve(this.response);
            } else {
                reject(new Error(this.statusText));
            }
        };
    });

    return promise;
};

getJSON("http://songfens.club:3000/goods/list?page=1&pageSize=8&sort=1&priceLevel=all").then(function (json) {
    console.log('Contents: ' + JSON.stringify(json));
    return json.result;
}, function (error) {
    console.error('出錯了', error);
})
    .then(x=> console.log(x.count));複製代碼


2. 請實現一個 uniq 函數,實現數組去重

例如:

uniq([7, 7, 2, 0, 8, 3, 6, 1, 2]);//[0, 1, 2, 3, 6, 7, 8]複製代碼

法 1: 利用 ES6 新增數據類型 Set

Set相似於數組,可是成員的值都是惟一的,沒有重複的值。

function uniq(arry) {
    return [...new Set(arry)];
}複製代碼

法 2: 利用 indexOf

function uniq(arry) {
    var result = [];
    for (var i = 0; i < arry.length; i++) {
        if (result.indexOf(arry[i]) === -1) {
            // 如 result 中沒有 arry[i], 則添加到數組中
            result.push(arry[i])
        }
    }
    return result;
}複製代碼

法 3: 利用 includes

function uniq(arry) {
    var result = [];
    for (var i = 0; i < arry.length; i++) {
        if (!result.includes(arry[i])) {
            // 如 result 中沒有 arry[i], 則添加到數組中
            result.push(arry[i])
        }
    }
    return result;
}複製代碼

法 4:利用 reduce

function uniq(arry) {
    return arry.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}複製代碼

法 5:利用 Map

function uniq(arry) {
    let map = new Map();
    let result = new Array();
    for (let i = 0; i < arry.length; i++) {
        if (map.has(arry[i])) {
            map.set(arry[i], true);
        } else {
            map.set(arry[i], false);
            result.push(arry[i]);
        }
    }
    return result;
}複製代碼



答案解析:

1、選擇題答案及解析

一、

考點:對 Array.prototype.map() 以及 parseInt() 方法的理解程度。

答案:D

解析:Array.prototype.map((value, index) => {})方法會將數組的值(value)和索引(index)傳給 parseInt() 方法並生成一個新數組,所以,上面的表達式也就至關於:

[

parseInt(0, 0), // 0

parseInt(1, 1), // NaN

parseInt(2, 2), // NaN

]

這裏順便問一下 Array.prototype.filter() 以及 Array.prototype.reduce() 的用法。

參考文檔:[Array.prototype.map()]、[parseInt()]


二、

考點:DOM 標籤的基本屬性。

答案:A

解析:title 屬性是當用戶鼠標移動到標籤上面時,做爲提示信息展現給用戶看的文本。

參考文檔:[img 標籤]


三、

考點:塊格式化上下文(BFC)。

答案:C

解析:A 和 D 應該沒有爭議。注意 B 選項 position 爲 absolute 或 fixed 纔會建立 BFC,relative 是不會建立 BFC 的。這裏能夠深刻問一下雙 margin 合併的問題。

參考文檔:[塊格式化上下文(BFC)]、[外邊距合併]


四、

考點:CSS 選擇器的優先級判斷。

答案:C

解析:規範中 CSS 選擇器的優先級分別是(從低到高):

1. 類型選擇器(<div>)、僞元素(::before)。

2. 類選擇(.class)、屬性選擇器([type="button"])、僞類(:hover)。

3. ID 選擇器(#id)。

當優先級相同的狀況,按照 CSS 樣式的執行順序肯定最終的優先級。

上面的代碼中 A 和 D 都是類型選擇器,所以小於 B 和 C 的類選擇器和屬性選擇器。而且因爲 C 在B 後面執行,因此最終的顏色是 C(blue)。

參考文檔:[CSS 優先級]


五、

考點:跨域資源共享(CORS)的一些常識的掌握程度。

答案:B

解析:這裏能夠順便問一下服務器應該如何響應預檢請求、以及JSONP 相關的知識點。

Access-Control-Allow-Origin: *

Access-Control-Allow-Methods: POST, GET, OPTIONS

Access-Control-Allow-Headers: Content-Type

Access-Control-Max-Age: 86400

參考文檔:[HTTP訪問控制(CORS)]


2、簡答題

一、

答案:

  • 正確答案: undefined

解釋:

這個問題,初一看感受答案很天然是1。由於從上到下執行下去,

if

語句中的條件應該爲

true

,由於"a"的確是沒有定義啊。 隨後,瓜熟蒂落地進入

var a = 1;

,最後,alert出來就應該是1。

而事實上,從JavaScript內部工做原理去看,在變量對象中講過, JavaScript處理上下文分爲兩個階段:

  • 進入執行上下文
  • 執行代碼

能夠理解爲,第一個階段是靜態處理階段,第二個階段爲動態處理階段【這裏指上下文執行過程】。

而在靜態處理階段,就會建立

變量對象(variable object)

,而且將變量申明做爲屬性進行填充。

到了執行階段,纔會根據執行狀況,來對變量對象中屬性(就是申明的變量)的值進行更新。

針對這個問題,其實際過程以下:

  • 進入執行上下文: 建立VO,並填充變量申明
    a
    ,VO以下所示:
VO(global) = {
    a: undefined
}複製代碼

因此,這個時候,a其實已經存在了。

  • 執行代碼: 進入
    if
    語句,發現條件判斷
    「a」 in window
    true。因而就不會進入if代碼塊,直接執行alert語句,所以,最終爲undefined


二、

答案:

同步代碼->微任務(process.nextTick 優先級大於 Promise.then)-> 宏任務(setImmediate)

end
nextTick
then
setImmediate複製代碼

三、

答案:

防抖函數的做用

防抖函數的做用就是控制函數在必定時間內的執行次數。防抖意味着 N 秒內函數只會被執行一次,若是 N 秒內再次被觸發,則 從新 計算延遲時間。

舉例說明: 小思最近在減肥,可是她很是吃吃零食。爲此,與其男友約定好,若是 10 天不吃零食,就能夠購買一個包 (不要問爲何是包,由於 包治百病)。可是若是中間吃了一次零食,那麼就要從新計算時間,直到小思堅持 10 天沒有吃零食,才能購買一個包。因此,管不住嘴的小思,沒有機會買包 (悲傷的故事)... 這就是 防抖

防抖函數實現

  1. 事件第一次觸發時,timeout 是 null,調用 later(),若 immediate 爲true,那麼當即調用 func.apply(this, params);若是 immediate 爲 false,那麼過 wait 以後,調用 func.apply(this, params)。
  2. 事件第二次觸發時,若是 timeout 已經重置爲 null(即 setTimeout 的倒計時結束),那麼流程與第一次觸發時同樣,若 timeout 不爲 null(即 setTimeout 的倒計時未結束),那麼清空定時器,從新開始計時。
function debounce(func, wait, immediate = true) {
    let timeout, result;
    // 延遲執行函數
    const later = (context, args) => setTimeout(() => {
        timeout = null;// 倒計時結束
        if (!immediate) {
            // 執行回調
            result = func.apply(context, args);
            context = args = null;
        }
    }, wait);
    let debounced = function (...params) {
        if (!timeout) {
            timeout = later(this, params);
            if (immediate) {
                // 當即執行
                result = func.apply(this, params);
            }
        } else {
            clearTimeout(timeout);
            // 函數在每一個等待時延的結束被調用
            timeout = later(this, params);
        }
        return result;
    }
    // 提供在外部清空定時器的方法
    debounced.cancel = function () {
        clearTimeout(timeout);
        timeout = null;
    };
    return debounced;
};複製代碼

immediate 爲 true 時,表示函數在每一個等待時延的開始被調用。immediate 爲 false 時,表示函數在每一個等待時延的結束被調用。

防抖的應用場景

  1. 搜索框輸入查詢,若是用戶一直在輸入中,沒有必要不停地調用去請求服務端接口,等用戶中止輸入的時候,再調用,設置一個合適的時間間隔,有效減輕服務端壓力。
  2. 表單驗證。
  3. 按鈕提交事件。
  4. 瀏覽器窗口縮放,resize 事件 (如窗口中止改變大小以後從新計算佈局) 等。
相關文章
相關標籤/搜索