3 JavaScript-kysymystä, joita kannattaa varoa koodaavien haastattelujen aikana

JavaScript on kaikkien nykyaikaisten selainten virallinen kieli. Sellaisina JavaScript-kysymyksiä tulee esiin kaikenlaisissa kehittäjähaastatteluissa.

Tämä artikkeli ei koske uusimpia JavaScript-kirjastoja, yleisiä kehityskäytäntöjä tai mitään uusia ES6-toimintoja. Pikemminkin kyse on kolmesta asiasta, jotka yleensä tulevat esiin haastatteluissa keskusteltaessa JavaScriptistä. Minulle itselleni on kysytty nämä kysymykset, ja ystäväni ovat kertoneet minulle, että heiltä on myös kysytty.

Nämä eivät tietenkään ole ainoat 3 asiaa, joita sinun tulisi tutkia ennen JavaScript-haastattelua - on monia tapoja valmistautua paremmin tulevaan haastatteluun - mutta alla on kolme kysymystä, joita haastattelija voi esittää arvioidakseen, kuinka hyvin tunnet ja ymmärrät JavaScript-kieli ja DOM.

Joten aloitetaan! Huomaa, että aiomme käyttää vaniljak JavaScriptiä alla olevissa esimerkeissä, koska haastattelija haluaa yleensä nähdä, kuinka hyvin ymmärrät JavaScriptiä ja DOM: ää ilman jQueryn kaltaisten kirjastojen apua.

Kysymys 1: Tapahtumavaltuuskunta

Kun rakennat sovellusta, sinun on joskus liitettävä tapahtumakuuntelijat sivun painikkeisiin, tekstiin tai kuviin jonkin toiminnon suorittamiseksi, kun käyttäjä on vuorovaikutuksessa elementin kanssa.

Jos otamme esimerkkinä yksinkertaisen todelistan, haastattelija saattaa kertoa haluavansa jonkin toiminnon tapahtuvan, kun käyttäjä napsauttaa yhtä luettelokohteista. Ja he haluavat sinun toteuttavan tämän toiminnon JavaScriptissä olettaen seuraavan HTML-koodin:


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

Voit kiinnittää tapahtumakuuntelijat elementteihin tekemällä jotain seuraavista:

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

Vaikka tämä toimii teknisesti, ongelmana on, että liität tapahtumakuuntelijan kuhunkin yksittäiseen kohteeseen erikseen. Tämä sopii 4 elementille, mutta entä jos joku lisää 10000 kohdetta (heillä voi olla paljon tehtävää) heidän todelliseen luetteloonsa? Sitten toiminto luo 10000 erillistä tapahtumakuuntelijaa ja liittää heidät DOM: iin. Tämä ei ole kovin tehokasta.

Haastattelussa olisi parasta ensin kysyä haastattelijalta, mikä on käyttäjän antamien elementtien enimmäismäärä. Jos se ei esimerkiksi voi koskaan olla yli 10, yllä oleva koodi toimisi hyvin. Mutta jos käyttäjän syötettävien kohteiden määrälle ei ole rajoituksia, haluat käyttää tehokkaampaa ratkaisua.

Jos sovelluksesi saattaa johtaa satojen tapahtumakuuntelijoiden joukkoon, tehokkaampi ratkaisu olisi liittää yksi tapahtumakuuntelija koko säilöön ja päästä sitten kaikkiin kohteisiin, kun sitä todella napsautetaan. Tätä kutsutaan tapahtuman delegoinniksi, ja se on paljon tehokkaampaa kuin erillisten tapahtumankäsittelijöiden liittäminen.

Tässä on tapahtuman valtuuttamisen koodi:

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

Kysymys # 2: Sulkimen käyttö silmukassa

Sulkemiset tuodaan joskus esiin haastattelussa, jotta haastattelija voi arvioida kuinka tunnet kielen ja tiedätkö milloin sulkemisen.

Sulkeminen on periaatteessa, kun sisäisellä toiminnolla on pääsy muuttujiin, jotka eivät kuulu sen soveltamisalaan. Sulkimia voidaan käyttää esimerkiksi yksityisyyden toteuttamiseen ja toimintotehtaiden luomiseen. Yleinen haastattelukysymys sulkemisten käytöstä on jotain tällaista:

Kirjoita funktio, joka selaa kokonaislukujen luetteloa ja tulostaa jokaisen elementin hakemiston 3 sekunnin viiveen jälkeen.

Yleinen (virheellinen) toteutus, jonka olen nähnyt tälle ongelmalle, näyttää tältä:

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

Jos suoritat tämän, huomaat, että saat oikeastaan 4 tulostettua joka kerta odotetun 0, 1, 2, 3 sijaan 3 sekunnin viiveen jälkeen.

Tunnistamiseksi oikein, miksi näin tapahtuu, olisi hyödyllistä ymmärtää miksi näin tapahtuu JavaScriptissä, mitä haastattelija yrittää testata.

Syynä tähän on se, että setTimeoutfunktio luo toiminnon (sulkemisen), jolla on pääsy ulompaan laajuuteensa, joka on silmukka, joka sisältää hakemiston i. Kolmen sekunnin kuluttua funktio suoritetaan ja se tulostaa arvon i, joka silmukan lopussa on 4: ssä, koska se kiertää 0, 1, 2, 3, 4 ja silmukka lopulta pysähtyy 4: ssä.

On todella muutama tapa kirjoittaa funktio tähän ongelmaan oikein. Tässä on kaksi niistä:

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

Kysymys # 3: Vapauttaminen

On joitain selaintapahtumia, jotka voivat käynnistyä useita kertoja lyhyessä ajassa hyvin nopeasti, kuten ikkunan koon muuttaminen tai sivun vieritys alaspäin. Jos liität tapahtumakuuntelijan esimerkiksi ikkunan vieritystapahtumaan ja käyttäjä vierittää sivua jatkuvasti alas nopeasti, tapahtumasi saattaa laukaista tuhansia kertoja 3 sekunnin kuluessa. Tämä voi aiheuttaa vakavia suorituskykyongelmia.

Jos keskustelet sovelluksen rakentamisesta haastattelussa, ja tapahtumia, kuten vieritys, ikkunan koon muuttaminen tai näppäimen painaminen, on syytä mainita poistaminen ja / tai kuristaminen keinona parantaa sivun nopeutta ja suorituskykyä. Todellinen esimerkki tästä vierasviestistä css-temppuilla:

Vuonna 2011 asia ilmestyi Twitter-verkkosivustolle: kun vieritit Twitter-syötteesi alas, se muuttui hitaaksi ja reagoimatta. John Resig julkaisi blogikirjoituksen ongelmasta, jossa selvitettiin kuinka paha idea on liittää scrolltapahtumaan kalliita toimintoja .

Purkaminen on yksi tapa ratkaista tämä ongelma rajoittamalla aikaa, joka kuluu ohi, kunnes funktio kutsutaan uudelleen. Oikea täytäntöönpano Debouncing näin ollen ryhmä useita toiminto vaatii yhteen ja suorittaa vain kerran, kun jonkin ajan kuluttua. Tässä on selkeä JavaScripti-toteutus, joka käyttää aiheita, kuten laajuus, sulkemiset, tämä ja ajoitetut tapahtumat:

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

Tämä toiminto - kun se on kääritty tapahtuman ympärille - suoritetaan vasta tietyn ajan kuluttua.

You would use this function like so:

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

Throttling is another technique that’s is similar to debouncing, except that instead of waiting for some time to pass by before calling a function, throttling just spreads the function calls across a longer time interval. So if an event occurs 10 times within 100 milliseconds, throttling could spread out each of the function calls to be executed once every 2 seconds instead of all firing within 100 milliseconds.

For more information on debouncing and throttling, the following articles and tutorials may be helpful:

  • Throttling and Debouncing in JavaScript
  • The Difference Between Throttling and Debouncing
  • Examples of Throttling and Debouncing
  • Remy Sharp’s blog post on Throttling function calls

Jos pidit tämän artikkelin lukemisesta, saatat haluta lukea JavaScript-oppaita ja ratkaista joitain JavaScript-koodauksen haasteita, joita isännöin Coderbyte-sivustossa. Haluaisin kuulla mielesi!