3 ЈаваСцрипт питања на која треба пазити током интервјуа за кодирање

ЈаваСцрипт је службени језик свих савремених веб прегледача. Као таква, ЈаваСцрипт питања се појављују у свим врстама интервјуа за програмере.

Овај чланак не говори о најновијим ЈаваСцрипт библиотекама, уобичајеним развојним праксама или било којој од нових ЕС6 функција. Уместо тога, ради се о 3 ствари које се обично појаве у интервјуима када се разговара о ЈаваСцрипт-у. И мени су постављана ова питања, а пријатељи су ми рекли да су и њих питали.

Наравно, ово нису једине 3 ствари које бисте требали проучити пре ЈаваСцрипт интервјуа - постоји мноштво начина на које се можете боље припремити за предстојећи интервју - али у наставку су наведена три питања која анкетар може поставити да процени колико добро знате и разумете језик ЈаваСцрипт и ДОМ.

Па кренимо! Имајте на уму да ћемо у доњим примерима користити ванилин ЈаваСцрипт, јер ће испитивач обично желети да види колико добро разумете ЈаваСцрипт и ДОМ без помоћи библиотека попут јКуери.

Питање # 1: Делегирање догађаја

Када градите апликацију, понекад ћете требати да прикачите преслушаваче догађаја на дугмад, текст или слике на страници како бисте извршили неку радњу када корисник ступи у интеракцију са елементом.

Ако за пример узмемо једноставну листу задатака, анкетар вам може рећи да жели да се акција догоди када корисник кликне на једну од ставки листе. И они желе да ову функцију примените у ЈаваСцрипт претпостављајући следећи ХТМЛ код:


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

Можда ћете желети да урадите нешто попут следећег да бисте елементе прикључили слушаоцима догађаја:

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

Иако ово технички функционише, проблем је у томе што слушалицу догађаја прикључујете на сваку појединачну ставку. Ово је у реду за 4 елемента, али шта ако неко на своју листу задатака дода 10.000 предмета (можда има много тога да уради)? Тада ће ваша функција створити 10.000 одвојених слушалаца догађаја и повезати сваког од њих у ДОМ. Ово није баш ефикасно.

У интервјуу би било најбоље прво испитивача питати који је максималан број елемената које корисник може унети. На пример, ако никада не може бити више од 10, онда би горњи код добро функционисао. Али ако не постоји ограничење броја ставки које корисник може унети, тада бисте желели да користите ефикасније решење.

Ако би ваша апликација могла да заврши са стотинама преслушача догађаја, ефикасније решење било би да се заправо прикачи један слушалац догађаја на цео контејнер, а затим да се приступи свакој ставци када се на њу стварно кликне. То се назива делегирање догађаја и много је ефикасније од додавања засебних руковалаца догађајима.

Ево кода за делегирање догађаја:

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: Коришћење затварача унутар петље

Затварања се понекад приказују у интервјуу како би анкетар могао да процени колико сте упознати са језиком и да ли знате када да примените затварање.

Затварање је у основи када унутрашња функција има приступ променљивим изван свог опсега. Затварачи се могу користити за ствари попут примене приватности и стварања фабрика функција. Уобичајено питање у вези са употребом затварача је отприлике овако:

Напишите функцију која ће се петљати кроз листу целих бројева и исписати индекс сваког елемента након кашњења од 3 секунде.

Уобичајена (нетачна) имплементација коју сам видео за овај проблем изгледа отприлике овако:

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

Ако ово покренете, видећете да се заправо сваки пут одштампа 4, уместо очекиваних 0, 1, 2, 3 након кашњења од 3 секунде.

Да би се тачно идентификовало зашто се то догађа, било би корисно имати разумевање зашто се то догађа у ЈаваСцрипт-у, што је управо оно што анкетар покушава да тестира.

Разлог томе је што 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++) { // 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: Отклањање

Постоје неки догађаји у прегледачу који се могу активирати много пута у кратком временском распону врло брзо, као што је промена величине прозора или помицање странице. Ако на пример прикачите слушалац догађаја на догађај помицања прозора, а корисник се врло брзо непрекидно помера по страници, ваш догађај се може активирати хиљаде пута у року од 3 секунде. То може довести до озбиљних проблема са перформансама.

Ако у интервјуу разговарате о изради апликације, а појаве се догађаји попут померања, промене величине прозора или притиска тастера, обавезно наведите отказивање и / или регулацију као начин за побољшање брзине и перформанси странице. Прави пример преузет из овог гостујућег поста на цсс-триковима:

2011. године на веб локацији Твиттер појавио се проблем: када сте помицали Твиттер феед, постало је споро и није реаговало. Јохн Ресиг објавио је пост на блогу о проблему где је објашњено колико је лоша идеја директно додавање скупих функција scrollдогађају.

Отказивање је један од начина за решавање овог проблема ограничавањем времена које треба проћи док се функција поново не позове. Исправна имплементација дебоунцинг би стога група неколико функција позива у један и да изврши само једном након неког времена је прошло. Ево примене у обичном ЈаваСцрипт-у која користи теме попут опсега, затварања, овог и временских догађаја:

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

Ова функција - када се омота око догађаја - извршиће се тек након што протекне одређено време.

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

Ако сте уживали у читању овог чланка, можда ће вам се свидети читање водича за ЈаваСцрипт и решавање неких изазова за кодирање ЈаваСцрипт-а које хостујем на Цодербите-у. Волео бих да чујем шта мислите!