对象的浅拷贝和深拷贝
原文链接:https://note.noxussj.top/?source=sifo
以下次要介绍了失常状况下的拷贝、浅拷贝、深拷贝三种形式的区别。
- 失常拷贝:复制一个对象,它们的内存地址是雷同的
- 浅拷贝:拷贝对象的第一层属性
- 深拷贝:拷贝对象多层的属性
失常拷贝
假如咱们要复制一个对象,如果不对其进行深拷贝,那么扭转其中一个对象后,另外一个对象也会跟着扭转。
const a = { age: 20 } const b = a b.age = 30 console.log(a.age) // 30
这并不是咱们想要的成果,所以想要复制一个全新的对象时,咱们能够通过浅拷贝来实现。
浅拷贝
形式一
const a = { name: 'xiaoming', age: 20 } const b = { name: a.name, age: a.age } b.age = 30 console.log(a.age) // 20
这种形式就不太灵便,要拷贝的对象属性越多,本人手写的属性就越多。
形式二
const a = { name: 'xiaoming', age: 20 } const b = {} for (const key in a) { b[key] = a[key] } b.age = 30 console.log(a.age) // 20
通过遍历的形式,无论旧对象的属性有多少个,都能够主动拷贝到新的对象上。 以上形式因为是浅拷贝只能拷贝对象的一层属性,对于对象有多层属性仍然是存在同样的问题。
const a = { name: 'xiaoming', age: 20, children: { name: 'libai', age: 20 } } const b = {} for (const key in a) { b[key] = a[key] }b.children.age = 30console.log(a.children.age) // 30
咱们把对象 b 的 children 属性扭转后,对象 a 的 children 属性也会跟着扭转,这也不是咱们想要的成果,所以咱们能够通过对象的深度拷贝实现(拷贝有限深的层级)。
深拷贝
形式一
const a = { name: 'xiaoming', age: 20, children: { name: 'libai', age: 20 } } const b = JSON.parse(JSON.stringify(a)) b.children.age = 30 console.log(a.children.age) // 20
通过 JSON 类来实现,实现起来非常简单,首先把对象转成 JSON 字符串,而后在把 JSON 字符串转成对象。然而这种形式仍然存在问题,假如我的对象外面有 function 属性等其余非值类型属性,那就无奈拷贝了。
const a = { name: 'xiaoming', age: 20, children: { name: 'libai', age: 20 }, eat: function () { console.log('i am eat') } } const b = JSON.parse(JSON.stringify(a)) console.log(b.eat) // undefined
形式二
应用递归(深度优先搜寻)形式,这种就是最稳固的一种形式,然而实现起来也是比较复杂,就是将对象的每一层属性都遍历进去,赋值给新的对象。
这里简略介绍一下什么是递归,就是在一个函数外部中再次调用本人,当达到肯定条件后进行调用。
// 类型字典 function type(data) { let dist = { '[object Array]': 'array', '[object Object]': 'object', '[object Number]': 'number', '[object Function]': 'function', '[object String]': 'string', '[object Null]': 'null', '[object Undefined]': 'undefined' } return dist[Object.prototype.toString.call(data)] } // 深度优先遍历 function dfs(data) { let newData if (type(data) === 'array') { newData = [] data.map((item, index) => { newData[index] = dfs(item) }) } else if (type(data) === 'object') { newData = {} Object.keys(data).map((item) => { newData[item] = dfs(data[item]) }) } else { newData = data } return newData }
const a = { name: 'xiaoming', age: 20, children: { name: 'libai', age: 20 }, eat: function () { console.log('i am eat') } } const b = dfs(a) b.eat() // i am eat
原文链接:https://note.noxussj.top/?source=sifo