Maison > Article > interface Web > Explications détaillées du code des trois problèmes les plus courants en JavaScript
JavaScript est le langage officiel de tous les navigateurs modernes. Par conséquent, des problèmes JavaScript surviennent dans Lors d'entretiens avec divers développeurs, cet article partage principalement avec vous les trois questions d'entretien les plus courantes en JavaScript. Les amis qui en ont besoin peuvent s'y référer ci-dessous. 🎜>Cet article ne concerne pas les dernières bibliothèques JavaScript, les pratiques de développement quotidiennes ou les nouvelles
fonctionsd'ES6, comme c'est souvent le cas lorsque l'on parle de JavaScript. Ces 3 questions reviennent dans les interviews. On m'a posé ces questions moi-même, et mes amis m'ont dit qu'elles avaient également été posées Bien sûr, vous ne devriez pas seulement apprendre ces 3 questions avant l'entretien JavaScript – Il existe de nombreuses façons de mieux vous préparer. pour votre prochain entretien – mais voici 3 questions que votre intervieweur peut poser pour déterminer votre compréhension du langage JavaScript et votre maîtrise du DOM Commençons : notez que nous utiliserons du JavaScript natif dans les exemples ! ci-dessous, car votre interlocuteur voudra généralement voir ce que vous faites sans l'aide d'une bibliothèque tierce (comme
jQuery) Comment comprendre JavaScript et DOM
.Question n°1 : Délégation d'événement
Remarque : Également appelée délégation d'événement, proxy temporel, etc. ;Lors de la création d'une application , vous devez parfois lier des écouteurs d'événements à des boutons, du texte ou des images sur la page afin d'effectuer certaines actions lorsque l'utilisateur interagit avec l'élément >Si nous prenons comme exemple une simple liste de tâches, la. L'intervieweur peut vous dire qu'il s'attend à ce qu'une action soit effectuée lorsque l'utilisateur clique sur l'un des éléments de la liste. Il souhaite que vous utilisiez JavaScript pour implémenter cette fonction :
<.>Vous souhaiterez peut-être lier un écouteur d'événement à l'élément comme suit :
Bien que cela fasse le travail, le problème est que vous liez les écouteurs d'événement à chaque élément de la liste individuellement, soit 4 éléments, ce n'est pas grave, mais si quelqu'un a quelque chose sur sa liste de choses à faire. Que se passe-t-il si vous ajoutez 10 000 éléments (ils peuvent avoir beaucoup à faire) ? Votre fonction créera alors 10 000 écouteurs d'événements indépendants et les liera ? chaque écouteur d'événement du DOM. Cette exécution de code est très inefficace Dans les entretiens, c'est une bonne idée de demander d'abord à l'intervieweur quel est le nombre maximum de choses que l'utilisateur peut saisir, et le code ci-dessus le fera. fonctionne bien s'il ne dépasse jamais 10. Cependant, s’il n’y a pas de limite au nombre d’éléments que l’utilisateur peut saisir, vous devez alors utiliser une solution plus efficace.Si votre application risque de se retrouver avec des centaines d'écouteurs d'événements, une solution plus efficace serait de lier un écouteur d'événements à l'ensemble du conteneur, puis de rendre chacun d'entre eux accessible lorsque vous cliquez réellement sur un élément exact. C'est ce qu'on appelle la délégation d'événements, et cela rend les gestionnaires d'événements de liaison individuellement pour chaque élément plus efficaces.
<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>Code utilisant la délégation d'événements :
document.addEventListener('DOMContentLoaded', function() { let app = document.getElementById('todo-app'); let items = app.getElementsByClassName('item'); // 将事件侦听器绑定到每个列表项 for (let item of items) { item.addEventListener('click', function() { alert('you clicked on item: ' + item.innerHTML); }); } });
Problème n°2 : Utiliser des fermetures à l'intérieur de boucles
Les fermetures reviennent souvent lors des entretiens afin que l'intervieweur puisse évaluer votre familiarité avec la langue et si vous savez quand utiliser les fermetures. L'essence d'une fermeture est qu'une
fonction interneaccède à des variables en dehors de sa portée. Les fermetures peuvent être utilisées pour implémenter des éléments tels que des variables privées et créer des fonctions d'usine. Une question d'entretien courante sur l'utilisation des fermetures ressemble à ceci : Écrivez une fonction qui parcourra une liste d'entiers et imprimera l'index de chaque élément après un délai de 3 secondes.
document.addEventListener('DOMContentLoaded', function() { let app = document.getElementById('todo-app'); // 事件侦听器绑定到整个容器上 app.addEventListener('click', function(e) { if (e.target && e.target.nodeName === 'LI') { let item = e.target; alert('you clicked on item: ' + item.innerHTML); } }); });
La façon la plus courante (mais incorrecte) de voir ce problème est avec une implémentation comme celle-ci : Si vous exécutez le code ci-dessus, après un 3 deuxième délai Vous verrez que la sortie imprimée est en fait 4 à chaque fois, au lieu du 0, 1, 2, 3 attendu.
Pour bien comprendre pourquoi cela se produit, il est utile d'être en JavaScript, ce qui est réellement l'intention de l'intervieweur.
La raison est que la fonction setTimeout crée une fonction qui peut accéder à sa portée externe (c'est-à-dire ce que nous appelons souvent une fermeture), et chaque boucle contient l'index i. Après 3 secondes, la fonction est exécutée et affiche la valeur de i, qui est 4 à la fin de la boucle car son cycle de boucle passe par 0,1,2,3,4, et la boucle s'arrête finalement à 4 .
Il existe en fait plusieurs manières correctes d'écrire ce problème. En voici deux :
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); }
Question n°3 : Fonction. anti-rebond
有一些浏览器事件可以在很短的时间内快速启动多次,例如调整窗口大小或向下滚动页面。例如,如果将事件侦听器绑定到窗口滚动事件上,并且用户继续非常快速地向下滚动页面,你的事件可能会在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() { // 通过 'this' 和 'arguments' // 获得函数的作用域和参数 let context = this; let args = arguments; // 如果事件被触发,清除 timer 并重新开始计时 clearTimeout(timer); timer = setTimeout(function() { fn.apply(context, args); }, delay); } }
当这个函数绑定在一个事件上,只有经过一段指定的时间后才会被调用。
你可以像这样去使用这个函数:
// 当用户滚动时函数会被调用 function foo() { console.log('You are scrolling!'); } // 在事件触发的两秒后,我们包裹在debounce中的函数才会被触发 let elem = document.getElementById('container'); elem.addEventListener('scroll', debounce(foo, 2000));
函数节流是另一个类似函数防抖的技巧,除了使用等待一段时间再调用函数的方法,函数节流还限制固定时间内只能调用一次。所以一个事件如果在100毫秒内发生10次,函数节流会每2秒调用一次函数,而不是100毫秒内全部调用。
总结
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!