一、赋值、浅拷贝与深拷贝的区别
二、深拷贝的方法
1.json转换
var targetObj = JSON.parse(JSON.stringify(copyObj))
缺点:
- 如果对象里有函数,函数无法被拷贝下来
- 无法拷贝copyObj对象原型链上的属性和方法
- 当数据的层次很深,会栈溢出
2.普通递归函数
function deepCopy(source){
if(!isObject(source)) return source; //如果不是对象的话直接返回
let target = Array.isArray(source) ? [] : {} //数组兼容
for (var i in source){
if(source.hasOwnProperty(i)){
if(typeof source[i] === 'object'){
target[i] = deepCopy(source[i])
}else{
target[i] = source[i]
}
}
}
return target
}
function isObject(obj){
return typeof obj === 'object' && obj !==null
}
缺点 - 无法保持引用
- 当数据的层次很深,会栈溢出
3.防栈溢出函数
function cloneLoop(x){
const root = {};
//栈
const loopList = [
{
parent:root,
key:undefined,
data:x,
}
];
while(loopList.length){
//深度优化
const node = loopList.pop();
const parent = node.parent;
const key = node.key;
const data = node.data;
//初始化赋值目标,key为undefined则拷贝到父元素,否则拷贝到子元素
let res = parent;
if(typeof key !== 'undefined'){
res = parent[key] = {};
}
for(let k in data){
if(data.hasOwnProperty(k)){
if(typeof data[k]==='object'){
//下一次循环
loopList.push({
parent:res,
key:k,
data:data[k],
});
}else{
res[k] = data[k];
}
}
}
}
return root;
}
优点:
- 不会栈溢出
- 支持很多层级的数据
function copyObject(orig){
var copy = Object.create(Object.getPrototypeOf(orig));//Object.getPrototypeOf返回指定对象的原型
copyOwnPropertiesFrom(copy,orig);
return copy;
}
function copyOwnPropertieaFrom(target,source){
Object
.getOwnPropertyNames(source)
.forEach(function (propKey){
var desc = Object.getOwnPropertyDescriptor(source,propKey);
Object.defineProperty(target,propKey,desc);
});
return target;
}
var obj = {
name: 'Jack',
age: '32',
job: 'developer'
};
var obj2 = copyObject(obj);
console.log(obj2);
obj.age = 39;
obj.name = 'Tom';
console.log(obj);
console.log(obj2);