今天面试遇到一道题,虽然并不难,但却涉及到了比较多的知识,在此分享一下。
现有对象obj = {a:1,b:{c:1,d:2}},要求经过转化后为{a:1,c:1,d:2}
遍历对象
for...in可以遍历对象的键,也可以获取到值
let obj = {a:1,b:{c:1,d:2}};
for(let key in obj){
console.log(obj[key]);
console.log(key)
}
// 1 a {c:1,d:2} b
判断类型
typeof 或 instanceof 判断每个属性的类型
(他们之间的区别在此不做过多讲述)
面试官:说说 typeof 和 instanceof 的区别 - 掘金 (juejin.cn)
for(let key in obj){
console.log(typeof(obj[key]))
}
// number object
由最初的想法,可以写出如下方法去解决该问题
let obj = {a:1,b:{c:1,d:2}} ;
let objTem = {}
function objChange(item){
for(let key in item){
// 判断是否为对象,若为对象则进行递归
if(typeof(item[key])==="object"){
this.objChange(item[key])
}else{
objTem[key] = item[key]
}
}
}
objChange(obj)
console.log(objTem)
// {a:1,c:1,d:2}
看似解决了问题,但紧接着面试官又抛出了另一个问题
在实际开发中,像`objTem`这个全局变量不应存在,应该尽可能避免不必要的全局变量
诶?
既然这样就需要在函数内部有一个临时变量去储存最后的结果,或者是当前递归处理后的结果
这时候就要考虑一个问题了,每次结果都是返回一个对象,如何将两个对象合并为一个对象?
合并对象 ( Object.assign(target,source) )
let objA= {a:1};
Object.assign(objA,{b:1});
console.log(objA);
// {a: 1, b: 1}
注意:这里的Object.assign是浅拷贝
(深浅拷贝在这里不做过多讲述)
Object.assign() - JavaScript | MDN (mozilla.org)
最终修改后的代码为
let obj = {a:1,b:{c:1,d:2}} ;
function objChange(item,objTem={}){
for(let key in item){
if(typeof(item[key])==="object"){
Object.assign(objTem,this.objChange(item[key]))
else{
objTem[key] = item[key]
}
}
return objTem
}
console.log( objChange(obj))
// {a: 1, c: 1, d: 2}
有其他方法欢迎讨论补充