目錄
問題#1: 事件代理
問題#2: 在循環中使用閉包
問題#3: Debouncing(防抖動)
首頁 web前端 js教程 3 個 JavaScript面試需要注意的問題

3 個 JavaScript面試需要注意的問題

Apr 05, 2017 pm 02:00 PM

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

本文不講最新的 JavaScript 函式庫,通用開發實踐,或任何新的 ES6 函數 。而是講講 3 個面試中常出現的 JavaScript 問題。我問過這些問題,我的朋友說他們也問。

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

讓我們開始吧!注意下面的範例我們使用原生 JavaScript, 因為面試官通常會想考查你在不借助函式庫(例如 jQuery)的幫助時掌握 JavaScript 和 DOM 的情況。

問題#1: 事件代理

建立應用程式時,有時需要給頁面中的按鈕,文字,或圖片新增事件監聽器,當使用者與這些元素互動時觸發某些操作。

我們以一個簡單的代辦事項清單為例,面試官會告訴你,他們希望在使用者點擊清單中某一項時觸發一個動作。並讓你用JavaScript 根據下面的HTML 程式碼實現這個功能:

<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>
登入後複製

你可能會像下面的程式碼一樣為元素添加事件監聽器:

document.addEventListener(&#39;DOMContentLoaded&#39;, function() {

  let app = document.getElementById(&#39;todo-app&#39;);
  let items = app.getElementsByClassName(&#39;item&#39;);

  // 给每个列表项添加事件监听器
  for (let item of items) {
    item.addEventListener(&#39;click&#39;, function() {
      alert(&#39;you clicked on item: &#39; + item.innerHTML);
    });
  }

});
登入後複製

當然上面的程式碼能完成面試官的需求,問題是每個清單項目都會加上一個事件監聽器。當清單只有 4 項時沒有問題,但如果有人給代辦事項清單新增了 10,000 個事項呢(他們也許有一大堆事情要做)?那時函數會建立 10,000 個事件監聽器,然後把它們都加到 DOM 上。這樣 效率 非常低。

面試中最好先問一下面試官使用者最多可以新增多少個代辦事項。如果永遠不會超過 10 個,那麼上面的程式碼運行起來就沒有問題。但如果使用者輸入待辦事項的數量沒有上限,那你就得換一個更有效率的解決方案。

如果應用程式有上百個事件監聽器,更有效率的解決方案是為最外層的容器添加一個 事件監聽器,當用戶真正點擊的時候再去獲取實際被點擊的代辦事項。這稱為 事件代理 ,這比給每個代辦事項都單獨添加事件監聽器更有效率。

下面是事件代理的程式碼:

document.addEventListener(&#39;DOMContentLoaded&#39;, function() {

  let app = document.getElementById(&#39;todo-app&#39;);

  // 给容器添加事件监听器
  app.addEventListener(&#39;click&#39;, function(e) {
    if (e.target && e.target.nodeName === &#39;LI&#39;) {
      let item = e.target;
      alert(&#39;you clicked on item: &#39; + item.innerHTML);
    }
  });

});
登入後複製

問題#2: 在循環中使用閉包

面試中經常會問到閉包,因為面試官可以通過這個問題的回答判斷你對語言的熟悉程度,以及檢視你是否知道什麼時候使用閉包。

閉包就是能存取作用域外部變數內部函數 。閉包能用來實現 私有化 和創建 工廠函數 等作用。關於閉包的常見面試題是這樣的:

寫一個函數,循環一個整數數組,延遲3 秒列印這個數組中每個元素的索引。

這個問題常見(不正確)的實作是這樣:

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log(&#39;The index of this number is: &#39; + i);
  }, 3000);
}
登入後複製

如果你執行這段函數,你會發現3 秒之後每次都印出來的是4 ,而不是預期的0, 1, 2, 3

為了正確的找到出現這種情況的原因,你需要理解 JavaScript 是如何運行這段程式碼的,這也是面試官想要考察你的地方。

原因是 setTimeout 函數建立了一個存取外部作用域的函數(閉包),就是包含索引 i 的那個循環。 3 秒之後,函數開始執行列印 i 的值,而此時循環也結束了, i 的值已經是 4。因為循環遍歷 0, 1, 2, 3, 4 後最終停在了 4。

其實有 好幾種方法 能 正確 解決這個問題。這裡有兩個:

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  // 给每个函数传入变量 i 让其能访问正确的索引
  setTimeout(function(i_local) {
    return function() {
      console.log(&#39;The index of this number is: &#39; + i_local);
    }
  }(i), 3000);
}
登入後複製
const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
  // 使用 ES6 中的 let 关键字,它会在函数调用时创建一个新的绑定
  // 了解更多:http://exploringjs.com/es6/ch_variables.html#sec_let-const-loop-heads
  setTimeout(function() {
    console.log(&#39;The index of this number is: &#39; + i);
  }, 3000);
}
登入後複製

問題#3: Debouncing(防抖動)

有些瀏覽器事件能在很短的時間內被觸發多次,例如調整視窗大小或捲動頁面。如果你為視窗滾動事件新增一個事件監聽器,然後使用者不停地快速向下捲動頁面,那你的事件可能在 3 秒之內被觸發數千次。這會導致非常嚴重的效能問題。

如果在面試中討論到構建應用程序,以及滾動事件,窗口調整事件,或者鍵盤事件等,請務必提及 debouncing 或者 throttling,作為提高頁面速度與性能的方法。來一個 css-tricks 的實例:

2011 年,Twitter 出了一個問題:當滾動 Twitter 摘要時,頁面變的很卡甚至沒有回應。 John Resig 寫了 一篇關於這個問題的部落格 ,解釋了直接將耗時的函數綁定在 scroll 事件上是一個多麼糟糕的想法。

Debouncing 是解决这个问题的一种方法,它的做法是限制下次函数调用之前必须等待的时间间隔。正确实现 debouncing 的方法是将若干个函数调用 合成 一次,并在给定时间过去之后仅被调用一次。下面是一个原生 JavaScript 的实现,用到了 作用域 , 闭包, this , 和 计时事件 :

// 将会包装事件的 debounce 函数
function debounce(fn, delay) {
  // 维护一个 timer
  let timer = null;
  // 能访问 timer 的闭包
  return function() {
    // 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
    let context = this;
    let args = arguments;
    // 如果事件被调用,清除 timer 然后重新设置 timer
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}
登入後複製

这个函数 — 当传入一个事件(fn)时 — 会在经过给定的时间(delay)后执行。

函数这样用:

// 当用户滚动时被调用的函数
function foo() {
  console.log(&#39;You are scrolling!&#39;);
}

// 在 debounce 中包装我们的函数,过 2 秒触发一次
let elem = document.getElementById(&#39;container&#39;);
elem.addEventListener(&#39;scroll&#39;, debounce(foo, 2000));
登入後複製

Throttling 是与 debouncing 类似的一种技术,但它不是在调用函数之前等待一段时间,throttling 是在较长的时间间隔内调用函数。所以如果一个事件每 100 毫秒被触发 10 次,throttling 会在每隔 2 秒时执行一次这个函数,而不是在 100 毫秒内执行 10 次事件。

 

以上是3 個 JavaScript面試需要注意的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

golang框架面試題集錦 golang框架面試題集錦 Jun 02, 2024 pm 09:37 PM

Go框架是一組擴充Go內建程式庫的元件,提供預製功能(例如網路開發和資料庫操作)。受歡迎的Go框架包括Gin(Web開發)、GORM(資料庫操作)和RESTful(API管理)。中間件是HTTP請求處理鏈中的攔截器模式,用於在不修改處理程序的情況下新增身份驗證或請求日誌記錄等功能。 Session管理透過儲存使用者資料來保持會話狀態,可以使用gorilla/sessions管理session。

See all articles