# 深浅拷贝
浅拷贝是把拷贝的对象复杂数据类型中的地址拷贝给目标对象,修改目标对象会影响被拷贝对象。
基本类型在进行浅拷贝时会被包装为对象。
深拷贝是完全克隆(拷贝的对象,而不是地址),修改目标对象不会影响被拷贝对象。
# 一、浅拷贝
Object.assign()
浅拷贝只是拷贝一层,更深层数对象级别的只拷贝引用。
# 1、原理
var obj = {
id: 1,
username: 'lencamo',
msg: {
age: 22 // 拷贝的只是msg的属性值的引用(当obj中age值发生改变时,target中的age值也会改变)}
}
}
var target = {}
for (var i in obj) {
o[i] = obj[k]
}
console.log(target)
# 2、示例
const target = { a: 1, b: 2 }
const source = { b: 4, c: 5 }
// Object.assign(target, source);
const returnedTarget = Object.assign(target, source)
console.log(target)
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget)
// expected output: Object { a: 1, b: 4, c: 5 }
# 3、应用
- 对象复制
const apiRoute = {
'/api/login': (req, res) => {
render(res, `{"ok":1}`)
}
}
const route = {
'/login': (req, res) => {
render(res, './static/login.html')
},
'/favicon.ico': (res) => {
render(req, res, './static/favicon.ico', 'image/x-icon')
}
// ……
}
// 实现路由合并
const Router = {}
Object.assign(Router, route)
Object.assign(Router, apiRoute)
- 合并对象
const o1 = { a: 1 }
const o2 = { b: 2 }
const o3 = { c: 3 }
const obj = Object.assign(o1, o2, o3)
console.log(obj) // { a: 1, b: 2, c: 3 }
console.log(o1) // { a: 1, b: 2, c: 3 }, target object itself is changed.
const o1 = { a: 1, b: 1, c: 1 }
const o2 = { b: 2, c: 2 }
const o3 = { c: 3 }
const obj = Object.assign({}, o1, o2, o3)
console.log(obj) // { a: 1, b: 2, c: 3 }
# 二、深拷贝
Object.assign()
深拷贝拷贝多层,每一级别的数据都会被拷贝。
目前实现深拷贝的方法不多,主要是两种:
- 利用 JSON 对象中的 parse 和 stringify
- 利用递归来实现每一层都重新创建对象并赋值
# 1、字符串的方式
let list = ['noodles', { list: ['eggs', 'flour', 'water'] }]
let list_deepcopy = JSON.parse(JSON.stringify(list))
// Change the value of the 'list' property in list_deepcopy.
list_deepcopy[1].list = ['rice flour', 'water']
// The 'list' property does not change in list.
console.log(list[1].list)
// Array(3) [ "eggs", "flour", "water" ]
# 2、递归的方式
var obj = {
id: 1,
username: 'lencamo',
msg: {
age: 22
}
}
var target = {}
// 递归应用
function deepCopy(newobj, oldobj) {
var item = oldobj[i]
if (item instanceof Array) {
newobj[i] = []
deepCopy(newobj[i], item)
} else if (item instanceof Object) {
newobj[i] = {}
} else {
newobj[k] = item
}
}
deepCopy(target, obj)
console.log(target)
# 三、拷贝数组
# 1、for 遍历
var arr1 = [1, 2, 3]
var arr2 = []
for (var i = 0; i < arr1.length; i++) {
arr2.push(arr1[i])
}
# 2、concat
var arr1 = [1, 2, 3]
var arr2 = arr1.concat()
// console.log(arr2)
# 3、map
var arr1 = [1, 2, 3]
var arr2 = arr1.map(function (item) {
return item
})
# 4、扩展运算符
var arr1 = [1, 2, 3]
let arr2 = [...arr]
// arr2.pop()
console.log(arr, arr2)
# 四、拷贝对象
# 1、展开运算符
let obj = {
name: 'lencamo'
}
let objT = {
...obj
}
console.log(objT)
# 2、assign
let obj = {
name: 'lencamo'
}
let obj0 = {}
let objT = Object.assign(obj0, obj)
console.log(objT)