问题 1: 事件委托代理在构建应用程序时,有时需要将事件绑定到页面上的按钮、文本或图像,以便在用户与元素交互时执行某些操作。如果我们以一个简单的待办事项列表为例,面试官可能会告诉你,当用户点击列表中的一个列表项时执行某些操作。他们希望你用 JavaScript 实现这个功能,假设有如下 HTML 代码:
[JavaScript] 纯文本查看 复制代码 <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>
你可能想要做如下操作来将事件绑定到元素:
[JavaScript] 纯文本查看 复制代码 document.addEventListener('DOMContentLoaded', function() {
let app = document.getElementById('todo-app');
let itimes = app.getElementsByClassName('item');
for (let item of items) {
item.addEventListener('click', function(){
alert('you clicked on item: ' + item.innerHTML);
})
}
})
虽然这在技术上是可行的,但问题是要将事件分别绑定到每个项。这对于目前 4 个元素来说,没什么大问题,但是如果在待办事项列表中添加了 10,000 项(他们可能有很多事情要做)怎么办?然后,函数将创建 10,000 个独立的事件侦听器,并将每个事件监听器绑定到 DOM ,这样代码执行的效率非常低下。 在面试中,最好先问面试官用户可以输入的最大元素数量是多少。例如,如果它不超过 10,那么上面的代码就可以很好地工作。但是如果用户可以输入的条目数量没有限制,那么你应该使用一个更高效的解决方案。 如果你的应用程序最终可能有数百个事件侦听器,那么更有效的解决方案是将一个事件侦听器实际绑定到整个容器,然后在单击它时能够访问每个列表项, 这称为 事件委托,它比附加单独的事件处理程序更有效。 下面是事件委托的代码: [JavaScript] 纯文本查看 复制代码 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)
}
})
})
问题 2: 在循环中使用闭包闭包常常出现在面试中,以便面试官衡量你对 JS 的熟悉程度,以及你是否知道何时使用闭包。 闭包基本上是内部函数可以访问其范围之外的变量。 闭包可用于实现隐私和创建函数工厂, 闭包常见的面试题如下: 编写一个函数,该函数将遍历整数列表,并在延迟3秒后打印每个元素的索引。 经常不正确的写法是这样的: [JavaScript] 纯文本查看 复制代码 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);
}
如果运行上面代码,3 秒延迟后你会看到,实际上每次打印输出是 4,而不是期望的 0,1,2,3 。 为了正确理解为什么会发生这种情况,了解为什么会在 JavaScript 中发生这种情况将非常有用,这正是面试官试图测试的内容。 原因是因为 setTimeout 函数创建了一个可以访问其外部作用域的函数(闭包),该作用域是包含索引 i 的循环。 经过 3秒后,执行该函数并打印出 i 的值,该值在循环结束时为 4,因为它循环经过0,1,2,3,4并且循环最终停止在 4。 [JavaScript] 纯文本查看 复制代码 const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
setTimeout(function(i_local){
return function () {
console.log('The index of this number is: ' + i_local);
}
}(i), 3000)
}
[JavaScript] 纯文本查看 复制代码 const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log('The index of this number is: ' + i);
}, 3000);
}
|