发布于 2026-01-06 0 阅读
0

JavaScript面试题

JavaScript面试题

这个月我参加了几次面试,我想分享一些技术面试中可能会遇到的好练习,以及我最初是如何应对这些练习的。

异步 for 循环

这个练习与异步编程的工作原理有关。如果让我选,我更想了解事件循环的工作原理,而不是问这个问题。

您将获得以下代码:

for(var i = 0; i < 10; i++){
    setTimeout(() => {
        console.log(i);
    }, 1000);
}
Enter fullscreen mode Exit fullscreen mode

然后你会被问到两个问题

  1. 输出结果是什么?
  2. 要如何才能打印出 0 到 9 之间的数字呢?

第一个问题的答案留给读者作为练习,但第二个问题应该已经给你一些提示了。
要回答第二个问题,你想要的是在每次迭代中存储变量的值,i以便之后可以访问它们。众多方法setTimeout之一是创建一个立即执行函数表达式(IIFE )(在这种情况下,或许称之为立即执行函数表达式辅助函数( IIAF )更合适?):

for(var i = 0; i < 10; i++){
    (n => {
        setTimeout(() => {
            console.log(n);
        }, 1000);
    })(i);
}
Enter fullscreen mode Exit fullscreen mode

奖金

您能否在评论中解释一下为什么这个小小的改动就能达到预期效果?

for(let i = 0; i < 10; i++){
    setTimeout(() => {
        console.log(i);
    }, 1000);
}
Enter fullscreen mode Exit fullscreen mode

减少

本练习的目标是定义一个函数,该函数执行与Array.prototype.reduce完全相同的操作,但接收数组作为第一个参数(很像lodash 的对应函数)。

迭代

对我来说,这是最直观的解决方案,即使用累加器来累积每次函数执行的结果。

function reduce(arr, fn, def) {
    let accum = def;
    for(let i = 0; i < arr.length; i++) {
        accum = fn(accum, arr[i]);
    }
    return accum;
}
Enter fullscreen mode Exit fullscreen mode

递归

递归版本需要了解一个特定的数组操作:移除数组的第一个元素,并得到一个包含剩余元素的数组。当然,我当时并不知道哪个函数能做到这一点,面试官很贴心地提到了`Array.prototype.slice`。另外需要说明的是,它Array.prototype.slice不会修改数组本身,而是返回数组的副本。

function reduce(arr, fn, def) {
    // base case: there are no more elements in the array and the function should finish
    if(arr.length === 0) {
        return def;
    }
    return reduce(arr.slice(1), fn, fn(def, arr[0]));
}
Enter fullscreen mode Exit fullscreen mode

极简主义

越来越多的人对推文大小的解决方案感兴趣,这种方案旨在尽可能减少解决方案所用的字符数,我认为在这里添加这种方案会是一个不错的练习。不过,我并不建议将这类解决方案直接添加到你的代码库中。

function reduce(arr, fn, def) {
    return arr.length === 0 ? def : reduce(arr.slice(1), fn, fn(def, arr[0]));
}
Enter fullscreen mode Exit fullscreen mode

地图

本练习要求你编写一个函数来复制Array.prototype.mapmap的行为

迭代

function map(arr, fn) {
    const result = [];
    for(const elem of arr) {
        result.push(fn(elem));
    }
    return result;
}
Enter fullscreen mode Exit fullscreen mode

使用减少

事情开始变得有趣起来。我被告知只能使用reduce之前实现的函数来编写 map 函数,我的第一个想法是这样做:

function map(arr, fn) {
    const result = [];
    reduce(arr, (curr, next) => {
        result.push(fn(next));
        return curr;
    });
    return result;
}
Enter fullscreen mode Exit fullscreen mode

这并没有错,但后来有人问“如果我们不想使用中间变量怎么办?”这让我开始思考……

function map(arr, fn) {
    return reduce(arr, (curr, next) => {
        curr.push(fn(next));
        return curr;
    }, []);
}
Enter fullscreen mode Exit fullscreen mode

极简主义

function map(arr, fn) {
    return reduce(arr, (curr, next) => curr.push(fn(next)) && curr, []);
}
Enter fullscreen mode Exit fullscreen mode

我在 CodeSandbox 中准备了一些示例程序,供你尝试解决:

  1. 减少
  2. 地图

有很多网站可以用来练习类似(或更复杂)的练习,例如HackerrankCodility

你还被要求做过其他什么有趣的练习吗?请在评论区告诉我!

文章来源:https://dev.to/a0viedo/javascript-interview-questions-17je