前言
在我们日常开发的时候对于对象的升维和降维不太常见,但是在我们面试的时候,这两玩意可是常客,接下来主包就给大家讲解一下前些时间被拷打的这两个操作。

1. 对象降维(扁平化)
看到扁平化想必大家都不陌生,在数组中的扁平化操作我们非常常见,接下来我们先来看一下对象的扁平化是什么样子 的:
简单来说呢就是让一个多维的对象变成一个一维的对象,这个一维对象中的key只有一层,并且每个key对应的是原来对象中的值,在了解完了什么是扁平化之后,我们接下来实现一下对对象扁平化的一个操作。
思路:
- 先创建一个新对象,然后对原对象进行遍历
- 如果key对应的value是原始类型则直接赋值给新对象
- 如果不是原始类型,则对其使用一个函数
help
进行一个递归的操作来获取到key对应的value- 返回生成的新对象
首先我们先定义一个flatObj(target)
函数,这个函数里面的主要部分为下面一段代码:
js
function flatObj(target) {
let res = {}
function help(target, oldKey) {} // 辅助遍历整个对象
help(target, '')
return res
}
在上面的这个函数中,我们在内部定义了一个help
函数,这个函数接收两个参数,第一个是我们要拿来扁平化的对象,第二个参数是我们扁平化之后对象中的key。而这个函数的核心功能就在help这个函数中,接下来我们来实现一下这个函数的功能,它的功能主要有以下几点:
- 遍历传入的target
- 我们需要凑出来一个新的key用来存值
- 判断
target[key]
是不是引用类型,如果是的话就再次调用help进行递归,否则就直接赋值即可
接下来我们来看完整代码:
js
const foo2 = {
"A": 1,
"B": {
"A": 2,
"B": 4
},
"CC": {
"D": {
"E": 3,
"F": 5
}
}
}
function flatObj(target) {
let res = {}
function help(target, oldKey) {
for (let key in target) {
// 凑出来新的key
let newKey
if (oldKey) {
if (Array.isArray(target)) {
newKey = `${oldKey}[${key}]`
} else {
newKey = `${oldKey}.${key}`
}
} else {
newKey = key
}
// 判断这个value是不是引用类型,不是就直接赋值
if (Object.prototype.toString.call(target[key]) === '[object Object]' || Array.isArray(target[key])) {
help(target[key], newKey)
} else {
res[newKey] = target[key]
}
}
}
help(target, '')
return res
}
console.log(flatObj(foo2));
2. 对象升维
在看完了对象的扁平化之后,相信对象的升维大家也不难理解,就是把一维对象转换为多维的。接下来我跟大家讲解一下大致思路:
- 先创建一个新对象
- 对原对象进行遍历,如果key当中没有'.'则代表是原始类型则直接赋值给新对象
- 如果value当中有'.'那么就代表升维后对象的该值是引用类型,需要额外的处理
- 返回得到的新对象
js
function fn(obj) {
let res = {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (key.indexOf('.') === -1) res[key] = obj[key]
else {
const list = key.split('.') // 获取生成新对象的key列表
const val = obj[key] // 储存对应的value
// 如果之前没有赋值的话,就创建一个新的对象,否则就用老的对象防止被覆盖
if (!res[list[0]]) {
res[list[0]] = {}
}
res[list[0]] = help(res[list[0]], val, list, 1)
}
}
}
return res
}
接下来我们来看一看其中help
函数的思路:
- 首先我们会传入四个参数,分别是:当前的对象,最后对应的value,key的列表,当前在哪一层对象中
- 接着我们在执行时先判断是不是到最后一层了,是的话直接返回val即可
- 如果没到达最后一层,我们就判断当前key位置它是否已经有值,没有的话就创造一个新对象给他,否则我们就在原来的基础上添加即可
tips:我们得防止引用丢失
js
const foo1 = {
'A': 1,
'B.A': 2,
'B.B': 4,
'CC.D.E': 3,
'CC.D.F': 5
}
function help(obj, val, list, index) {
if (index === list.length) return val
// 防止值被覆盖
if (!obj[list[index]]) {
obj[list[index]] = {};
}
obj[list[index]] = help(obj[list[index]], val, list, index + 1)
return obj
}
function fn(obj) {
let res = {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (key.indexOf('.') === -1) res[key] = obj[key]
else {
const list = key.split('.')
const val = obj[key]
if (!res[list[0]]) {
res[list[0]] = {}
}
res[list[0]] = help(res[list[0]], val, list, 1)
}
}
}
return res
}
console.log(fn(foo1));