亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

3個(gè)經(jīng)常被問(wèn)到的 JavaScript 面試題

Galence / 2544人閱讀

摘要:更高效的解決方案是將一個(gè)事件偵聽(tīng)器實(shí)際綁定到父容器上,然后在實(shí)際單擊時(shí)可以訪問(wèn)每個(gè)確切元素。如果將事件偵聽(tīng)器綁定到窗口滾動(dòng)事件上,并且用戶快速滾動(dòng)頁(yè)面,事件很可能會(huì)在短時(shí)間多次觸發(fā)。

原文鏈接

問(wèn)題 #1: 事件委托

事件委托,也叫事件委派,事件代理。

當(dāng)構(gòu)建應(yīng)用程序時(shí),有時(shí)需要將事件監(jiān)聽(tīng)器綁定到頁(yè)面上的某些元素上,以便在用戶與元素交互時(shí)執(zhí)行某些操作。

假設(shè)我們現(xiàn)在有一個(gè)無(wú)序列表:

  • Walk the dog
  • Pay bills
  • Make dinner
  • Code for one hour

我們需要在

  • 上綁定點(diǎn)擊事件,我們可能會(huì)這樣操作:

    app = document.getElementById("todo-app");
    let items = app.getElementsByClassName("item");
    
    // 將事件偵聽(tīng)器綁定到每個(gè)列表項(xiàng)
    for (let item of items) {
      item.addEventListener("click", function() {
        alert("you clicked on item: " + item.innerHTML);
      });
    }

    雖然這樣可以實(shí)現(xiàn)功能,但問(wèn)題是要多帶帶將事件偵聽(tīng)器綁定到每個(gè)列表項(xiàng)。這是4個(gè)元素,沒(méi)什么大問(wèn)題,但如果列表中有10,000個(gè)事項(xiàng),怎么辦?這個(gè)函數(shù)將會(huì)創(chuàng)建10,000個(gè)獨(dú)立的事件監(jiān)聽(tīng)器,并將每個(gè)事件監(jiān)聽(tīng)器綁定到 DOM 。這樣代碼執(zhí)行的效率非常低下。

    更高效的解決方案是將一個(gè)事件偵聽(tīng)器實(shí)際綁定到父容器

      上,然后在實(shí)際單擊時(shí)可以訪問(wèn)每個(gè)確切元素。這被稱為事件委托,并且它比每個(gè)元素多帶帶綁定事件的處理程序更高效。

      那么上面的代碼可以改變?yōu)椋?/p>

      let app = document.getElementById("todo-app");
        
      // 事件偵聽(tīng)器綁定到整個(gè)容器上
      app.addEventListener("click", function(e) {
        if (e.target && e.target.nodeName === "LI") {
          let item = e.target;
          alert("you clicked on item: " + item.innerHTML);
        }
      });
      問(wèn)題 #2: 在循環(huán)內(nèi)使用閉包(Closures)

      閉包的本質(zhì)是一個(gè)內(nèi)部函數(shù)訪問(wèn)其作用域之外的變量。閉包可以用于實(shí)現(xiàn)諸如 私有變量 和 創(chuàng)建工廠函數(shù)之類的東西。

      在面試中我們可能會(huì)見(jiàn)到一段這樣的代碼:

      for (var i = 0; i < 4; i++) {
        setTimeout(function() {
          console.log(i);
        }, 1000);
      }

      運(yùn)行上面的代碼控制臺(tái)會(huì)在1秒后打印4個(gè)4,而不是0,1,2,3。

      其原因是因?yàn)?b>setTimeout函數(shù)創(chuàng)建了一個(gè)可以訪問(wèn)其外部作用域的函數(shù)(也就是我們經(jīng)常說(shuō)的閉包),每個(gè)循環(huán)都包含了索引i。

      1秒后,該函數(shù)被執(zhí)行并且打印出i的值,其在循環(huán)結(jié)束時(shí)為4,因?yàn)樗难h(huán)周期經(jīng)歷了0,1,2,3,4,并且循環(huán)最終在4時(shí)停止。

      下面列舉兩種方案解決這個(gè)問(wèn)題:

      for (var i = 0; i < 4; i++) {
        // 通過(guò)傳遞變量 i
        // 在每個(gè)函數(shù)中都可以獲取到正確的索引
        setTimeout(function(j) {
          return function() {
            console.log(j);
          }
        }(i), 1000);
      }
      for (let i = 0; i < 4; i++) {
        // 使用ES6的let語(yǔ)法,它會(huì)創(chuàng)建一個(gè)新的綁定
        // 每個(gè)方法都是被多帶帶調(diào)用的
        setTimeout(function() {
          console.log(i);
        }, 1000);
      }
      問(wèn)題 #3: 函數(shù)防抖(Debouncing)

      有一些瀏覽器事件可以在很短的時(shí)間內(nèi)快速啟動(dòng)多次,例如頁(yè)面滾動(dòng)事件。如果將事件偵聽(tīng)器綁定到窗口滾動(dòng)事件上,并且用戶快速滾動(dòng)頁(yè)面,事件很可能會(huì)在短時(shí)間多次觸發(fā)。這可能會(huì)導(dǎo)致一些嚴(yán)重的性能問(wèn)題。

      因此,在偵聽(tīng)滾動(dòng),窗口調(diào)整大小,或鍵盤(pán)按下的事件時(shí),請(qǐng)務(wù)必使用函數(shù)防抖動(dòng)(Debouncing)函數(shù)節(jié)流(Throttling)來(lái)提升頁(yè)面速度和性能。

      函數(shù)防抖(Debouncing)是解決這個(gè)問(wèn)題的一種方式,通過(guò)限制需要經(jīng)過(guò)的時(shí)間,直到再次調(diào)用函數(shù)。一個(gè)實(shí)現(xiàn)函數(shù)防抖的方法是:把多個(gè)函數(shù)放在一個(gè)函數(shù)里調(diào)用,隔一定時(shí)間執(zhí)行一次。

      這里有一個(gè)使用原生JavaScript實(shí)現(xiàn)的例子,用到了作用域、閉包、this和定時(shí)事件:

      function debounce(fn, delay) {
        // 持久化一個(gè)定時(shí)器 timer
        let timer = null;
        // 閉包函數(shù)可以訪問(wèn) timer
        return function() {
          // 通過(guò) "this" 和 "arguments" 獲得函數(shù)的作用域和參數(shù)
          let self = this;
          let args = arguments;
          // 如果事件被觸發(fā),清除 timer 并重新開(kāi)始計(jì)時(shí)
          clearTimeout(timer);
          timer = setTimeout(function() {
            fn.apply(self, args);
          }, delay);
        }
      }
      
      // 當(dāng)用戶滾動(dòng)時(shí)調(diào)用函數(shù)foo()
      function foo() {
        console.log("You are scrolling!");
      } 
      
      // 在事件觸發(fā)的兩秒后,包裹在debounce()中的函數(shù)才會(huì)被觸發(fā)
      window.addEventListener("scroll", debounce(foo, 2000));

      函數(shù)節(jié)流是另一個(gè)類似函數(shù)防抖的技巧,除了使用等待一段時(shí)間再調(diào)用函數(shù)的方法,函數(shù)節(jié)流還限制固定時(shí)間內(nèi)只能調(diào)用一次。所以,如果一個(gè)事件在100毫秒內(nèi)發(fā)生10次,函數(shù)節(jié)流會(huì)每2秒調(diào)用一次函數(shù),而不是100毫秒內(nèi)全部調(diào)用。

      (完)

  • 文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

    轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/88170.html

    相關(guān)文章

    • Javascript 面試經(jīng)常被問(wèn)到的個(gè)問(wèn)!

      摘要:相反,在討論時(shí),面試中通常會(huì)提到三件事。而認(rèn)為最后一個(gè)參賽者說(shuō)了算,只要還能吃的,就重新設(shè)定新的定時(shí)器。試想,如果用戶的操作十分頻繁他每次都不等設(shè)置的時(shí)間結(jié)束就進(jìn)行下一次操作,于是每次都為該用戶重新生成定時(shí)器,回調(diào)函數(shù)被延遲了不計(jì)其數(shù)次。本文不是討論最新的 JavaScript 庫(kù)、常見(jiàn)的開(kāi)發(fā)實(shí)踐或任何新的 ES6 函數(shù)。相反,在討論 JavaScript 時(shí),面試中通常會(huì)提到三件事。我自己...

      chnmagnus 評(píng)論0 收藏0
    • Javascript 面試經(jīng)常被問(wèn)到的個(gè)問(wèn)!

      摘要:相反,在討論時(shí),面試中通常會(huì)提到三件事。通過(guò)對(duì)事件對(duì)應(yīng)的回調(diào)函數(shù)進(jìn)行包裹以自由變量的形式緩存時(shí)間信息,最后用來(lái)控制事件的觸發(fā)頻率。而認(rèn)為最后一個(gè)參賽者說(shuō)了算,只要還能吃的,就重新設(shè)定新的定時(shí)器。 showImg(https://segmentfault.com/img/bVboH5x?w=1000&h=750); 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 本...

      PrototypeZ 評(píng)論0 收藏0
    • Vue面試中,經(jīng)常會(huì)被問(wèn)到的面試/Vue知識(shí)點(diǎn)整理

      摘要:可以在該鉤子中進(jìn)一步地更改狀態(tài),不會(huì)觸發(fā)附加的重渲染過(guò)程。我工作中只用到,對(duì)和不怎么熟與的區(qū)別相同點(diǎn)都支持指令內(nèi)置指令和自定義指令都支持過(guò)濾器內(nèi)置過(guò)濾器和自定義過(guò)濾器都支持雙向數(shù)據(jù)綁定都不支持低端瀏覽器。 看看面試題,只是為了查漏補(bǔ)缺,看看自己那些方面還不懂。切記不要以為背了面試題,就萬(wàn)事大吉了,最好是理解背后的原理,這樣面試的時(shí)候才能侃侃而談。不然,稍微有水平的面試官一看就能看出,是...

      mengbo 評(píng)論0 收藏0
    • 前端實(shí)習(xí)面試的一些建議

      摘要:作者今年大三,在春招過(guò)程中參加了多家大公司的面試后,拿到了騰訊的前端實(shí)習(xí),在這里做一些總結(jié),希望給還未參加過(guò)實(shí)習(xí)面試的同學(xué)一些幫助。在之后的面試時(shí)就更加從容一些了。 作者今年大三,在春招過(guò)程中參加了多家大公司的面試后,拿到了騰訊的前端實(shí)習(xí) offer,在這里做一些總結(jié),希望給還未參加過(guò)實(shí)習(xí)面試的同學(xué)一些幫助。 一、簡(jiǎn)歷的準(zhǔn)備 簡(jiǎn)歷制作是很重要的一個(gè)環(huán)節(jié),一份好的簡(jiǎn)歷會(huì)給面試官留下很不錯(cuò)...

      Rango 評(píng)論0 收藏0
    • 一位大佬的親身經(jīng)歷總結(jié):簡(jiǎn)歷和面試的技巧

      摘要:我覺(jué)得了解簡(jiǎn)歷和面試的技巧可以幫助你更好的去學(xué)習(xí)重要的知識(shí)點(diǎn)以及更好地去準(zhǔn)備面試以及面試,說(shuō)實(shí)話,我個(gè)人覺(jué)得這些東西還挺重要的。在本文里,我將介紹我這段時(shí)間里更新簡(jiǎn)歷和面試的相關(guān)經(jīng)歷。 分享一篇很不錯(cuò)的文章!本文作者曾經(jīng)寫(xiě)過(guò)《Java Web輕量級(jí)開(kāi)發(fā)面試教程》和 《Java核心技術(shù)及面試指南》這兩本書(shū)。我覺(jué)得了解簡(jiǎn)歷和面試的技巧可以幫助你更好的去學(xué)習(xí)重要的知識(shí)點(diǎn)以及更好地去準(zhǔn)備面試以...

      pingan8787 評(píng)論0 收藏0

    發(fā)表評(píng)論

    0條評(píng)論

    最新活動(dòng)
    閱讀需要支付1元查看
    <