首頁 > web前端 > js教程 > 主體

JavaScript中最常見的三個問題的程式碼詳解

黄舟
發布: 2017-03-23 14:49:03
原創
1068 人瀏覽過

JavaScript是所有現代瀏覽器的官方語言。 因此,JavaScript 問題出現在各種開發人員的面試中。

前言

本文不是在講述最新的JavaScript函式庫,日常的開發實作或任何新的ES6 函數

。在面試中出現這3個問題。問題– 這裡有很多方法可以讓你更好地準備即將到來的面試– 但面試官可能會問到下面是3個問題,來判斷你對JavaScript語言的理解和DOM的掌握程度。 #讓我們開始吧!如何理解JavaScript 和DOM 的。 ;

當建立應用程式時,有時你需要將事件監聽器綁定到頁面上的按鈕,文字或圖像上,以便在使用者與元素互動時執行某些操作。

#如果我們以一個簡單的待辦事項清單為例,面試官可能會告訴你,他們希望在使用者點擊其中一個清單項目時需要執行某些操作。他們希望你用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);
 });
 }
 
});
登入後複製

雖然這個實作了功能,問題是您要單獨將事件偵聽器綁定到每個清單項目。事項(他們可能有很多事情要做)怎麼辦? 在面試中,最好先詢問面試官使用者可以輸入事項的最大數量是多少。但是,如果使用者可以輸入的事項數量沒有限制,那麼你應該使用一個更有效率的解決方案。 如果你的應用程式最終可能有幾百個事件監聽器,更有效率的解決方案是將一個事件偵聽器實際綁定到整個容器上,然後在實際單擊時可以存取每個確切元素。這被稱為事件委託,並且它每個元素單獨綁定事件處理

程式更有效率。

用事件委託的程式碼:

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: 在迴圈內使用閉包(Closures)

閉包常常在面試中出現,以便麵試官衡量你對這門語言的熟悉程度,以及是否知道何時使用閉包。

閉包的本質是一個內部函數

存取其作用域之外的變數。閉包可以用於實現諸如 私有變數 和 創建工廠函數之類的東西。關於使用閉包的常見面試問題是這樣的:

編寫一個函數,它將循環遍歷整數列表,並在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的值,其在循環結束時為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)来提升页面速度和性能。一个真实的案例,来自 guest post on css-tricks:

在2011年,一个问题在Twitter上被提出:当你滚动Twitter feed时,它会会变得非常慢甚至未响应。John Resig 就这个问题发布了一篇博文,它解释了直接绑定函数到scroll事件上是多么糟糕的事。

函数防抖动(Debouncing) 是解决这个问题的一种方式,通过限制需要经过的时间,直到再次调用函数。一个正确实现函数防抖的方法是:把多个函数放在一个函数里调用,隔一定时间执行一次。这里有一个使用原生JavaScript实现的例子,用到了作用域、闭包、this和定时事件:

// debounce函数用来包裹我们的事件
function debounce(fn, delay) {
 // 持久化一个定时器 timer
 let timer = null;
 // 闭包函数可以访问 timer
 return function() {
 // 通过 &#39;this&#39; 和 &#39;arguments&#39;
 // 获得函数的作用域和参数
 let context = this;
 let args = arguments;
 // 如果事件被触发,清除 timer 并重新开始计时
 clearTimeout(timer);
 timer = setTimeout(function() {
 fn.apply(context, args);
 }, delay);
 }
}
登入後複製

当这个函数绑定在一个事件上,只有经过一段指定的时间后才会被调用。

你可以像这样去使用这个函数:

// 当用户滚动时函数会被调用
function foo() {
 console.log(&#39;You are scrolling!&#39;);
}
 
// 在事件触发的两秒后,我们包裹在debounce中的函数才会被触发
let elem = document.getElementById(&#39;container&#39;);
elem.addEventListener(&#39;scroll&#39;, debounce(foo, 2000));
登入後複製

函数节流是另一个类似函数防抖的技巧,除了使用等待一段时间再调用函数的方法,函数节流还限制固定时间内只能调用一次。所以一个事件如果在100毫秒内发生10次,函数节流会每2秒调用一次函数,而不是100毫秒内全部调用。

总结

以上是JavaScript中最常見的三個問題的程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!