亚洲福利网站,国产精品久久国产三级国电话系列 ,欧美久久久久久,蜜桃av在线

IT培訓(xùn)-高端面授IT培訓(xùn)機(jī)構(gòu)
云和教育:云和數(shù)據(jù)集團(tuán)高端IT職業(yè)教育品牌
  • 國家級
    全民數(shù)字素養(yǎng)與技能培訓(xùn)基地
  • 河南省
    第一批產(chǎn)教融合型企業(yè)建設(shè)培育單位
  • 鄭州市
    數(shù)字技能人才(碼農(nóng))培養(yǎng)評價(jià)聯(lián)盟

面試官常考的幾道JavaScript面試題

  • 發(fā)布時間:
    2017-02-28
  • 版權(quán)所有:
    云和教育
  • 分享:

JavaScript 是所有現(xiàn)代瀏覽器的官方語言。因此,各種語言的開發(fā)者面試中都會遇到 JavaScript 問題。

本文不講最新的 JavaScript 庫,通用開發(fā)實(shí)踐,或任何新的 ES6 函數(shù)。而是講講面試中經(jīng)常出現(xiàn)的 3 個 JavaScript 問題。我問過這些問題,我的朋友說他們也問。

當(dāng)然不是說你在準(zhǔn)備 JavaScript 面試時只要學(xué)習(xí)這 3 個問題 —— 你還有很多途徑去更好的準(zhǔn)備即將到來的面試 —— 但面試官很有可能通過下面 3 個問題來判斷你了解和掌握 JavaScript 和 DOM 的情況。

讓我們開始吧!注意下面的例子中我們使用原生 JavaScript, 因?yàn)槊嬖嚬偻ǔO肟疾槟阍诓唤柚鷰欤ɡ?jQuery)的幫助時掌握 JavaScript 和 DOM 的情況。

問題 1: 事件代理

創(chuàng)建應(yīng)用時,有時需要給頁面中的按鈕,文字,或圖片添加事件監(jiān)聽器,當(dāng)用戶與這些元素交互時觸發(fā)某些操作。

我們以一個簡單的代辦事項(xiàng)列表為例,面試官會告訴你,他們希望在用戶點(diǎn)擊列表中某一項(xiàng)時觸發(fā)一個動作。并讓你用 JavaScript 根據(jù)下面的 HTML 代碼實(shí)現(xiàn)這個功能:

<ul id=”todo-app”>

<li class=”item”>Walk the dog</li>

<li class=”item”>Pay bills</li>

<li class=”item”>Make dinner</li>

<li class=”item”>Code for one hour</li></ul>

你可能會像下面的代碼一樣給元素添加事件監(jiān)聽器:

document.addEventListener(‘DOMContentLoaded’, function() {

let app = document.getElementById(‘todo-app’);

let items = app.getElementsByClassName(‘item’);

// 給每個列表項(xiàng)添加事件監(jiān)聽器

for (let item of items) {

item.addEventListener(‘click’, function() {

alert(‘you clicked on item: ‘ + item.innerHTML);

});

}});

當(dāng)然上面的代碼能完成面試官的需求,問題是每個列表項(xiàng)都會加上一個事件監(jiān)聽器。當(dāng)列表只有 4 項(xiàng)時沒有問題,但如果有人給代辦事項(xiàng)列表新增了 10,000 個事項(xiàng)呢(他們也許有一大堆事情要做)?那時函數(shù)會創(chuàng)建 10,000 個事件監(jiān)聽器,然后把它們都添加到 DOM 上。這樣效率非常低。

面試中最好首先問一下面試官用戶最多可以添加多少個代辦事項(xiàng)。如果永遠(yuǎn)不會超過 10 個,那上面的代碼運(yùn)行起來就沒有問題。但如果用戶輸入待辦事項(xiàng)的數(shù)量沒有上限,那你就得換一個更高效的解決方案。

如果應(yīng)用有上百個事件監(jiān)聽器,更高效的解決方案是給最外層的容器添加一個事件監(jiān)聽器,當(dāng)用戶真正點(diǎn)擊的時候再去獲取實(shí)際被點(diǎn)擊的代辦事項(xiàng)。這被稱為事件代理,這比給每個代辦事項(xiàng)都單獨(dú)添加事件監(jiān)聽器更高效。

下面是事件代理的代碼:

document.addEventListener(‘DOMContentLoaded’, function() {

let app = document.getElementById(‘todo-app’);

// 給容器添加事件監(jiān)聽器

app.addEventListener(‘click’, function(e) {

if (e.target && e.target.nodeName === ‘LI’) {

let item = e.target;

alert(‘you clicked on item: ‘ + item.innerHTML);

}

});});

問題 2: 在循環(huán)中使用閉包

面試中經(jīng)常會問到閉包,因?yàn)槊嬖嚬倌芡ㄟ^這個問題的回答判斷你對語言的熟悉程度,以及考察你是否知道什么時候使用閉包。

閉包就是能訪問作用域外部變量的內(nèi)部函數(shù) 。閉包能用來實(shí)現(xiàn)私有化和創(chuàng)建工廠函數(shù)等作用。關(guān)于閉包的常見面試題是這樣的:

寫一個函數(shù),循環(huán)一個整數(shù)數(shù)組,延遲 3 秒打印這個數(shù)組中每個元素的索引。

這個問題常見(不正確)的實(shí)現(xiàn)是這樣:

const arr = [10, 12, 15, 21];

for (var i = 0; i < arr.length; i++) {

setTimeout(function() {

console.log(‘The index of this number is: ‘ + i);

}, 3000);

}

如果你運(yùn)行這段函數(shù),你會發(fā)現(xiàn) 3 秒之后每次都打印的是 4,而不是預(yù)期的 0, 1, 2, 3。

為了正確的找到出現(xiàn)這種情況的原因,你需要理解 JavaScript 是如何運(yùn)行這段代碼的,這也是面試官想要考察你的地方。

原因是 setTimeout 函數(shù)創(chuàng)建了一個訪問外部作用域的函數(shù)(閉包),就是包含索引 i 的那個循環(huán)。3 秒之后,函數(shù)開始執(zhí)行打印 i 的值,而此時循環(huán)也結(jié)束了,i 的值已經(jīng)是 4。因?yàn)檠h(huán)遍歷 0, 1, 2, 3, 4 后最終停在了 4。

實(shí)際上有好幾種方法能正確解決這個問題。這里有兩個:

const arr = [10, 12, 15, 21];for (var i = 0; i < arr.length; i++) {

// 給每個函數(shù)傳入變量 i 讓其能訪問正確的索引

setTimeout(function(i_local) {

return function() {

console.log(‘The index of this number is: ‘ + i_local);

}

}(i), 3000);}

const arr = [10, 12, 15, 21];for (let i = 0; i < arr.length; i++) {

// 使用 ES6 中的 let 關(guān)鍵字,它會在函數(shù)調(diào)用時創(chuàng)建一個新的綁定

// 了解更多:http://exploringjs.com/es6/ch_variables.html#sec_let-const-loop-heads

setTimeout(function() {

console.log(‘The index of this number is: ‘ + i);

}, 3000);}

問題 3: Debouncing(防抖動)

有些瀏覽器事件能在很短的時間內(nèi)被觸發(fā)多次,例如調(diào)整窗口大小或滾動頁面。如果你給窗口滾動事件添加一個事件監(jiān)聽器,然后用戶不停地快速向下滾動頁面,那你的事件可能在 3 秒之內(nèi)被觸發(fā)數(shù)千次。這會導(dǎo)致非常嚴(yán)重的性能問題。

如果在面試中討論到構(gòu)建應(yīng)用程序,以及滾動事件,窗口調(diào)整事件,或者鍵盤事件等,請務(wù)必提及 debouncing 或者 throttling,作為提高頁面速度與性能的方法。來一個 css-tricks 的實(shí)例:

2011 年,Twitter 出了一個問題:當(dāng)滾動 Twitter 摘要時,頁面變的很卡甚至無響應(yīng)。John Resig 寫了一篇關(guān)于這個問題的博客,解釋了直接將耗時的函數(shù)綁定在 scroll 事件上是一個多么糟糕的想法。

Debouncing 是解決這個問題的一種方法,它的做法是限制下次函數(shù)調(diào)用之前必須等待的時間間隔。正確實(shí)現(xiàn) debouncing 的方法是將若干個函數(shù)調(diào)用 合成 一次,并在給定時間過去之后僅被調(diào)用一次。下面是一個原生 JavaScript 的實(shí)現(xiàn),用到了作用域, 閉包, this, 和 計(jì)時事件:

// 將會包裝事件的 debounce 函數(shù)function debounce(fn, delay) {

// 維護(hù)一個 timer

let timer = null;

// 能訪問 timer 的閉包

return function() {

// 通過 ‘this’ 和 ‘a(chǎn)rguments’ 獲取函數(shù)的作用域和變量

let context = this;

let args = arguments;

// 如果事件被調(diào)用,清除 timer 然后重新設(shè)置 timer

clearTimeout(timer);

timer = setTimeout(function() {

fn.apply(context, args);

}, delay);

}}

這個函數(shù) — 當(dāng)傳入一個事件(fn)時 — 會在經(jīng)過給定的時間(delay)后執(zhí)行。

函數(shù)這樣用:

// 當(dāng)用戶滾動時被調(diào)用的函數(shù)function foo() {

console.log(‘You are scrolling!’);}// 在 debounce 中包裝我們的函數(shù),過 2 秒觸發(fā)一次let elem = document.getElementById(‘container’);elem.addEventListener(‘scroll’, debounce(foo, 2000));

Throttling 是與 debouncing 類似的一種技術(shù),但它不是在調(diào)用函數(shù)之前等待一段時間,throttling 是在較長的時間間隔內(nèi)調(diào)用函數(shù)。所以如果一個事件每 100 毫秒被觸發(fā) 10 次,throttling 會在每隔 2 秒時執(zhí)行一次這個函數(shù),而不是在 100 毫秒內(nèi)執(zhí)行 10 次事件。

主站蜘蛛池模板: 威海市| 泸溪县| 泰安市| 昂仁县| 葵青区| 柘荣县| 博罗县| 凤翔县| 龙里县| 崇阳县| 永济市| 西盟| 双柏县| 达孜县| 陇川县| 青田县| 龙陵县| 惠安县| 新建县| 韶山市| 措美县| 张家港市| 同江市| 万源市| 定南县| 宁夏| 遂平县| 嘉鱼县| 永丰县| 木里| 河东区| 临安市| 金阳县| 巩义市| 三河市| 中牟县| 灵宝市| 富裕县| 剑川县| 牡丹江市| 高州市|