原始对象数据
var obj = {
id: 1,
name: 'zs',
info:{
sex : "female"
},
color: ["red","pink","yellow"]
}
要拷贝到的新对象
var o = {}
浅拷贝
浅拷贝只拷贝一层,对象值完全复制,深层次只是拷贝引用,并且会影响原始对象值(有些数组方法是不改变原始值)
1. 循环赋值
for(var k in obj){
// console.log(k); //id name info
// console.log(obj[k]) //1 zs
o[k] = obj[k]
// console.log(o[k]); //1 zs
}
console.log(o); //{id: 1, name: 'zs', info: {sex:'female'}, color: Array(3)}
-------修改新对象里的性别值,发现原始对象和新对象值都变了-----------
console.log(o); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'male'} name: "zs"
o.info.sex = "male"
console.log(obj); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'male'} name: "zs"
2. Object.assign() 语法糖
Object.assign(o,obj) //第一个参数是要拷贝到的数组,第二个是拷贝的对象
console.log(o); //{id: 1, name: 'zs', info: {sex: 'female'}, color: Array(3)}
-------修改新对象里的性别值,发现原始对象和新对象值都变了-----------
console.log(o); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'male'} name: "zs"
o.info.sex = "male"
console.log(obj); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'male'} name: "zs"
3. concat() 适用数组
var oldArr = [0,1,2,[3,4]]
var newArr = oldArr.concat()
console.log(...oldArr); // 0 1 2 [3, 4] 原始值不改变
newArr[1] = 0
console.log(...newArr) //0 0 2 [3, 4] 还是继续引用深层次数组
4. slice() 适用数组
var oldArr = [0,1,2,[3,4]]
var newArr = oldArr.slice(0)
console.log(...oldArr); // 0 1 2 [3, 4] 原始值不改变
newArr[1] = 0
console.log(...newArr) //0 0 2 [3, 4] 还是继续引用深层次数组
5. Array.from() 适用数组
var oldArr = [0,1,2,[3,4]]
var newArr = Array.from(oldArr)
console.log(...oldArr); // 0 1 2 [3, 4] 原始值不改变
newArr[1] = 0
console.log(...newArr) //0 0 2 [3, 4] 还是继续引用深层次数组
6. ...扩展运算符 适用数组
var oldArr = [0,1,2,[3,4]]
var newArr = [...oldArr]
console.log(...oldArr); // 0 1 2 [3, 4] 原始值不改变
newArr[1] = 0
console.log(...newArr) //0 0 2 [3, 4] 还是继续引用深层次数组
深拷贝
深拷贝全部复制,不会影响原始对象值
1. 封装函数
但是这个方法值为undefined拷贝会把原始值也会成undefined
function DeepClone(newObj,oldObj){
for(var k in oldObj){
var item = oldObj[k]; //获取属性值
// console.log(item); //1 zs {sex: 'female'} ["red","pink","yellow"]
if(item instanceof Array){ //先判断属性值是否数组,先判断Object,数组属于Object,会跳过后续判断数组的条件
newObj[k] = [] //将旧数组属性值(["red","pink","yellow"])给新数组的属性(newObj[k],相当于obj.color,它必须是一个数组接收)
DeepClone(newObj[k],item) //递归,把属性值给新数组属性
}else if(item instanceof Object){ //判断属性值是否对象
newObj[k] = {} //将旧对象属性值({sex: 'female'})给新数组的属性(newObj[k],相当于obj.info,它必须是一个对象接收)
DeepClone(newObj[k],item)
}else{
newObj[k] = item
}
}
}
DeepClone(o,obj)
-------修改新对象里的性别值,发现原始对象没变,新对象变了-----------
console.log(o); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'male'} name: "zs"
o.info.sex = "male"
console.log(obj); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'female'} name: "zs"
2. JSON.parse(JSON.stringify())
var o = JSON.parse(JSON.stringify(obj))
-------修改新对象里的性别值,发现原始对象没变,新对象变了-----------
console.log(o); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'male'} name: "zs"
o.info.sex = "male"
console.log(obj); //color: (3) ['red', 'pink', 'yellow'] id: 1 info: {sex: 'female'} name: "zs"
缺点:这个方法值为undefined拷贝会跳过,并且原始值也会变,函数和symbol则会跳过
var obj = {
name: 'A',
name1: undefined,
name3: function() {},
name4: Symbol('A')
}
var o = JSON.parse(JSON.stringify(obj))
console.log(o); //{name: 'A'}
o.name = "male"
console.log(obj); //{name: 'A', name1: undefined, name4: Symbol(A), name3: ƒ}