大家伙儿都知道,有时候面试官特意给你留道“送分题”,手写个 `flat` 就是这样。这玩意儿主要就是看你基本功稳不稳,说白了就是搞懂需求、能不能玩递归、边界处理行不行。 先说说这 `flat` 到底是干啥的。它长在 `Array.prototype` 上,专门把多层嵌套的数组“拍扁”成一条线。不传参数默认拍一层,想拍几层传个数字就行。要是传了 `Infinity`,那就是“死缠烂打”,一直拍到底;传个小于等于0的数,就直接原样返回。记住,这方法不改原数组,只给你返回个新的。 咱们拆分一下思路,把这活儿变成几大块儿。 第一步是把数组里的每一个子项都揪出来。你可以选 `for` 循环、`for...of`、`forEach` 或者 `reduce`,这儿我比较喜欢 `reduce`,一边往里加元素一边看还得不得再往后递归。 第二步得看看手里拿的是个啥东西。你是想用 `instanceof` 呢?还是 `Object.prototype.toString.call`?最省心的还是直接用 `Array.isArray()`,这个在跨窗口或者跨帧的环境下都挺稳当。 第三步就是把拿到的数组拆开来,让它们变成逗号分隔的一串参数。这里扩展运算符 `...` 用起来最直观;要是老古董浏览器不认这玩意儿,咱们也能用 `concat.apply` 来凑数,原理其实是一样的,就是把数组里的参数挨个传进去。 最后一步最关键,一旦发现手里拿的还是个数组,立马再调自己一遍。核心逻辑就一句:“item 是数组吗?那我就先 flat(item) 再加上结果数组。”如果怕栈溢出的话,可以试试用栈或者尾递归来优化一下。 把这思路拼一块儿,就有了下面这段能跑的代码。面试的时候咱们别着急动手写逻辑,先把注释写明白了再写代码,能少犯很多语法错误。 这段代码其实只递归了一层,但靠着 `reduce` 的闭包记忆机制,每回递归都在偷偷减少深度,最后总能把多维数组给“拖”成一条线。现场把这玩意儿写出来基本就能拿分了;要是想再保险点(比如把空位跳过、处理循环引用),就在判断逻辑那儿再加个条件判断就行啦。