浅复制与深复制
1. 浅复制
浅复制最大的特点就是对于对象,只复制对象引用
一. Object.assign(),对象融合
var a = {
prop: 'haha',
hello: 'Hi world',
obj: {
inner: 'yes'
}
}
var b = Object.assign({}, a);
a.obj === b.obj; // true
二. spread操作符
var c = {...a};
a.obj === c.obj; // true
三. for-in遍历
function clone(obj){
var result = {};
for(let p in obj){
result[p] = obj[p];
}
return result;
}
var d = clone(a);
a.obj === d.obj; // true
2. 深拷贝
一. JSON方法
注意遇到函数和值为undefined的属性会被自动忽略(还有Symbol)
var a = {
prop: 'haha',
hello: 'Hi world',
obj: {
inner: 'yes'
},
udf: undefined,
nul: null,
fun: function(t){return t;}
}
var b = JSON.stringify(a);
b = JSON.parse(b);
// b.udf 和 b.fun 属性丢失了
a.obj === b.obj; // false
二. 递归遍历
- 处理常见的数组和普通对象
- for-in遍历的话会丢弃不可枚举属性
- 使用hasOwnProperty过滤原型属性
function deepClone(obj){
// 基本值
if(typeof obj !== 'object' || obj === null){
return obj;
}
// 复杂值
var result = Array.isArray(obj) ? [] : {};
for(let p in obj){
if(obj.hasOwnProperty(p)){
result[p] = deepClone(obj[p]);
}
}
return result;
}
var b = deepClone(a);
b.obj === a.obj; // false
- 出现循环引用的话,要用的
weakMap
; - 对于
Date
、RegExp
等使用Object.prototype.toString.call()
深度区分