浅拷贝
浅拷贝是指复制对象的时候,指对第一层键值对进行独立的复制
function shallowCopy(target){
if(!target || typeof target !== 'object'){
return
}
let newObj = Array.isArray(target)? []:{}
for(var key in target){
if(target.hasOwnProperty(key)){
newObj[key]= target[key]
}
}
return newObj
}
传入数组成功
var arr = [1,2,3,4,5]
var arr2 = shallowCopy(arr)
console.log(arr2);//[1, 2, 3, 4, 5]
obj2[1] = 'js'
console.log(arr) //[1, 2, 3, 4, 5]
console.log(arr2)[1, "js", 3, 4, 5]
传入对象时成功
var obj = {
"name" :'zhao',
"age":16,
'j':[1,2,3,4,5]
}
var obj2 = shallowCopy(obj)
console.log(obj2)
但是遇到一个问题
var obj2 = shallowCopy(obj)
console.log(obj2);
obj2.skill.a = 'js'
obj2.name = 'xiaoz'
console.log(obj.name)
console.log(obj2.name)
console.log(obj.skill.a)
console.log(obj2.skill.a)
对于skill这个属性,obj2变量复制的是它在堆中的地址,这也导致了obj和obj2的skill其实是指向堆中的同一个对象。 如果想要更深层次的拷贝,就需要用到深拷贝了
深拷贝
深拷贝还可以利用JSON的方式。
JSON.parse(JSON.stringify(obj));
对于一般的需求是可以满足的,但是它有缺点。下例中,可以看到JSON复制会忽略掉值为undefined以及函数表达式。
var obj = {
"name" :'zhao',
"age":16,
'j':[1,2,3,4,5],
"c":undefined,
"skill":{
'a':'css'
},
sum: function() { return age; }
}
var obj2 = JSON.parse(JSON.stringify(obj));
console.log(obj2);
/* [object Object] {
age: 16,
j: [1, 2, 3, 4, 5],
name: "zhao",
skill: [object Object] {
a: "css"
}
}*/
深拷贝
deepCopy = (target )=>{
if(!target || typeof target !== 'object'){
return
}
let newObj = Array.isArray(target)?[]:{};
for(let key in target ){
//判断类型
if(typeof target[key] === 'object'){
if(Array.isArray(target[key])){
//是数组
newObj[key] = target[key].map(item=>this.deepCopy(item))
}else{
//是对象
//递归
newObj[key] = this.deepCopy(target[key])
}
}else if(typeof target[key] === 'function'){
//递归
newObj[key] = target[key].bind(newObj)
}else{
newObj[key] = target[key]
}
}
return newObj
}
const obj = {
a: 1,
b: {a:1},
c: { d: {b:1}, g: () => {console.log('hi')} },
e: () =>{console.log('112')},
f: function () {}
}
let obj2 = deepCopy(obj)
obj.c.d.b = '222'
console.log(obj.c.d.b) //"222"
console.log(obj2.c.d.b) //1
深拷贝成功