3 JavaScript-kérdés, amelyre figyelni kell az interjúk kódolásakor

A JavaScript az összes modern webböngésző hivatalos nyelve. Mint ilyen, a JavaScript-kérdések mindenféle fejlesztői interjúban felmerülnek.

Ez a cikk nem a legújabb JavaScript-könyvtárakról, általános fejlesztési gyakorlatokról vagy az új ES6-funkciókról szól. Inkább 3 dologról van szó, amelyek általában az interjúk során merülnek fel a JavaScript megbeszélésekor. Magam is feltették ezeket a kérdéseket, és a barátaim azt mondták, hogy nekik is feltették őket.

Természetesen nem ez az egyetlen 3 dolog, amelyet tanulmányoznia kell egy JavaScript-interjú előtt - számos lehetőség kínálkozik arra, hogy jobban felkészülhessen egy közelgő interjúra - de az alábbiakban 3 kérdést tehetünk fel, amelyet egy kérdező feltesz, hogy megítélje, mennyire ismeri és érti a JavaScript nyelv és a DOM.

Tehát kezdjük! Ne feledje, hogy az alábbi példákban vanília JavaScript-et fogunk használni, mivel kérdezője általában szeretné megtudni, mennyire érti jól a JavaScriptet és a DOM-ot olyan könyvtárak segítsége nélkül, mint a jQuery.

1. kérdés: Az esemény delegálása

Alkalmazás készítésekor néha eseményhallgatókat kell csatolnia az oldalon található gombokhoz, szövegekhez vagy képekhez annak érdekében, hogy valamilyen műveletet hajtson végre, amikor a felhasználó interakcióba lép az elemgel.

Ha egy egyszerű Todo listát veszünk példának, akkor az interjúztató elmondhatja, hogy azt akarja, hogy cselekedjen, amikor a felhasználó rákattint a lista egyik elemére. És azt akarják, hogy a következő HTML kódot feltételezve valósítsa meg ezt a funkciót a JavaScript-ben:

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

Érdemes a következőkhöz hasonlóan csatlakoztatni az eseményhallgatókat az elemekhez:

document.addEventListener('DOMContentLoaded', function() { let app = document.getElementById('todo-app'); let items = app.getElementsByClassName('item'); // attach event listener to each item for (let item of items) { item.addEventListener('click', function() { alert('you clicked on item: ' + item.innerHTML); }); } });

Bár ez technikailag működik, a probléma az, hogy egy eseményhallgatót minden egyes elemhez külön-külön csatol. Ez négy elem esetében rendben van, de mi van akkor, ha valaki 10 000 elemet (sok dolgot is megtehet) hozzáad a todo listájához? Ezután a funkciója 10 000 külön eseményhallgatót hoz létre, és mindegyiket csatolja a DOM-hoz. Ez nem túl hatékony.

Egy interjúban az lenne a legjobb, ha először megkérdeznénk az interjúztatót, hogy mekkora lehet a felhasználók maximális száma. Ha például soha nem lehet több 10-nél, akkor a fenti kód jól működik. De ha a felhasználó által beírható elemek számának nincs korlátozva, akkor hatékonyabb megoldást szeretne használni.

Ha alkalmazása több száz eseményhallgatóval járhat, akkor a hatékonyabb megoldás az lenne, ha egy eseményfigyelőt ténylegesen az egész tárolóhoz csatolna , majd hozzáférhetne az egyes elemekhez, amikor azokra valóban rákattintanak. Ezt hívják esemény delegálásnak, és sokkal hatékonyabb, mint külön eseménykezelők csatolása.

Az esemény delegálásának kódja:

document.addEventListener('DOMContentLoaded', function() { let app = document.getElementById('todo-app'); // attach event listener to whole container app.addEventListener('click', function(e) { if (e.target && e.target.nodeName === 'LI') { let item = e.target; alert('you clicked on item: ' + item.innerHTML); } }); });

2. kérdés: Zárás használata hurokban

A lezárásokat néha egy interjú során hozzák fel, hogy a kérdező felmérhesse, mennyire ismeri a nyelvet, és tudja-e, hogy mikor kell végrehajtani a lezárást.

A bezárás alapvetően az, amikor egy belső funkció hozzáfér a hatókörén kívül eső változókhoz. A bezárások felhasználhatók például a magánélet megvalósítására és a funkciógyárak létrehozására. A lezárások használatával kapcsolatos gyakori interjúk kérdése ilyesmi:

Írjon egy függvényt, amely végiglapozza az egész számokat, és 3 másodperces késleltetés után kinyomtatja az egyes elemek indexét.

A probléma gyakori (helytelen) megvalósítása a következőképpen néz ki:

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); }

Ha ezt futtatja, akkor látni fogja, hogy a várt 0, 1, 2, 3 helyett 3 másodperces késés után minden alkalommal kinyomtatja a 4- et .

Ahhoz, hogy helyesen azonosítsuk, miért történik ez, hasznos lenne megérteni, hogy miért történik ez a JavaScript-ben, pontosan ezt próbálja tesztelni a kérdező.

Ennek oka az, hogy a setTimeoutfüggvény létrehoz egy olyan funkciót (bezárást), amely hozzáfér a külső hatóköréhez, amely az indexet tartalmazó hurok i. 3 másodperc elteltével a függvény végrehajtásra kerül, és kiírja annak értékét i, amely a hurok végén 4-nél van, mert 0, 1, 2, 3, 4 cikluson keresztül halad, és a hurok végül 4-nél megáll.

A probléma függvényének valójában néhány módja van a funkció helyes megírásának. Íme kettő közülük:

const arr = [10, 12, 15, 21]; for (var i = 0; i < arr.length; i++) { // pass in the variable i so that each function // has access to the correct index 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++) { // using the ES6 let syntax, it creates a new binding // every single time the function is called // read more here: //exploringjs.com/es6/ch_variables.html#sec_let-const-loop-heads setTimeout(function() { console.log('The index of this number is: ' + i); }, 3000); }

3. kérdés: Beszámoló

Vannak olyan böngészőesemények, amelyek rövid időn belül nagyon sokszor képesek elindulni, például egy ablak átméretezése vagy egy oldal lefelé görgetése. Ha például egy eseményfigyelőt csatol az ablakgörgető eseményhez, és a felhasználó folyamatosan gyorsan görgeti lefelé az oldalt, akkor az esemény több ezerszer képes elindulni 3 másodpercen belül. Ez komoly teljesítményproblémákat okozhat.

Ha egy interjúban egy alkalmazás létrehozásáról vitatkozik, és olyan események jönnek létre, mint a görgetés, az ablak átméretezése vagy a billentyű megnyomása, mindenképpen említse meg a visszavonást és / vagy a fojtást az oldal sebességének és teljesítményének javítására. Valódi példa a css-tricks vendég bejegyzéséből:

2011-ben egy probléma jelent meg a Twitter webhelyén: amikor a Twitter-hírcsatornán görgette lefelé, az lassúvá vált és nem reagált. John Resig egy blogbejegyzést tett közzé a problémáról, ahol elmagyarázták, milyen rossz ötlet drága funkciókat közvetlenül csatolni az scrolleseményhez.

A visszavonás a probléma egyik megoldási módja azáltal, hogy korlátozza az idő múlását, amíg egy függvény újra nem hívódik meg. A visszavonás helyes megvalósítása tehát több függvényhívást egybe csoportosít, és csak egyszer hajt végre bizonyos idő elteltével. Itt van egy egyszerű JavaScript-ben megvalósított megvalósítás, amely olyan témákat használ fel, mint a hatókör, a lezárások, ez és az események időzítése:

// debounce function that will wrap our event function debounce(fn, delay) { // maintain a timer let timer = null; // closure function that has access to timer return function() { // get the scope and parameters of the function // via 'this' and 'arguments' let context = this; let args = arguments; // if event is called, clear the timer and start over clearTimeout(timer); timer = setTimeout(function() { fn.apply(context, args); }, delay); } }

Ez a funkció - amikor egy esemény köré van tekerve - csak egy bizonyos idő elteltével fog végrehajtani.

Ezt a funkciót így használná:

// function to be called when user scrolls function foo() { console.log('You are scrolling!'); } // wrap our function in a debounce to fire once 2 seconds have gone by let elem = document.getElementById('container'); elem.addEventListener('scroll', debounce(foo, 2000));

A fojtás egy másik technika, amely hasonló a visszavonáshoz, azzal a különbséggel, hogy ahelyett, hogy egy funkció meghívása előtt várna egy kis időt, a fojtás csak hosszabb időintervallumban terjeszti a függvényhívásokat. Tehát, ha egy esemény tízszer fordul elő 100 milliszekundumon belül, a fojtás eloszthatja az egyes funkcióhívásokat, amelyeket 2 másodpercenként egyszer kell végrehajtani, ahelyett, hogy minden 100 milliszekundumon belül elindulna.

További információk a visszavonásról és a fojtásról a következő cikkek és oktatóanyagok lehetnek hasznosak:

  • Fojtás és visszavonás a JavaScript-ben
  • A fojtás és a visszavonás közötti különbség
  • Példák fojtásra és visszavonásra
  • Remy Sharp blogbejegyzése a Fojtó funkció hívásokról

If you enjoyed reading this article, then you may like reading the JavaScript tutorials and solving some of the JavaScript coding challenges that I host on Coderbyte. I’d love to hear what you think!