前几个月是面试的高峰期,我在群里看到了有几个小伙伴在面试时被问到了这样一个问题:
Q:封装一个函数key,传入两个参数,第一个为指定对象;第二个为指定的层次。函数作用是返回一个对象中指定层次的所有键名
例如现在有这样一个对象
let obj = { name: { a: 1, b: 2, c: { o: 9, p: 10, q: 11 } }, age: { m: 3, n: 4 } }
现在调用三次函数,分别为 key(obj, 1) 、key(obj, 2) 、key(obj, 3) 则得到以下结果
key(obj, 1) // 返回结果:['name', 'age']key(obj, 2) // 返回结果:['a', 'b', 'c', 'm', 'n']key(obj, 3) // 返回结果:['o', 'p', 'q']
看它们当时讨论得挺激烈,方法各异,当时我就一想呀,这其实考察得就是一个递归,先递归获取每一层的键值,然后最后返回就可以了,我们来看一下代码思路是如何的吧
A: 首先我们规定一下在递归过程中,存储数据的数据结构如何,结构类似这样:
let arr = [ ['name', 'age'], // 存放对象第一层的所有键值 ['a', 'b', 'c', 'm', 'n'], // 存放对象第二层的所有键值 ['o', 'p', 'q'] // 存放对象第三层的所有键值]
然后就来写一下封装的函数代码
function key(o, level) { // 创建空数组用于存储每个层次的键值 let arr = [] // 封装一个内部函数用于递归调用 function from(ob, l) { // 遍历对象ob的第 l+1 层次的所有键值 Object.keys(ob).forEach(key => { // 将key值添加到 arr 中存储 if(arr[l]) arr[l].push(key); else { arr[l] = [key] } // 这里做了一些优化,即不需要将原对象每一层都遍历出来 if(l !== level - 1) { // 继续深入遍历下一层所有键名 from(ob[key], l + 1) } }) } // 从原对象的第一层开始遍历 from(o, 0) // 最后直接返回我们要的那一层的键值就可以啦 return arr[level - 1] }
所有的封装思路我都写在注释里啦,大家可以仔细看看,也可以亲自动手写一写。
另外说一点小技巧,我在代码中其实略微得做了一点优化,这会给面试官留下很好的印象,因为他会发现你很细心,还会注意提高代码的运行效率。所以也建议你们在面试的过程中,在能力范围内对代码优化一下,会更加分哦~
本次的面试题就到这儿啦。我是Lpyexplore,一个前端的探索者,关注我~带你了解不一样的前端干货