浅拷贝实现
1. for···in只循环第一层
// 只复制第一层的浅拷贝
function simpleCopy(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
for (let i in obj1) {
obj2[i] = obj1[i];
}
return obj2;
}
var obj1 = {
a: 1,
b: 2,
c: {
d: 3
}
}
var obj2 = simpleCopy(obj1);
obj2.a = 3;
obj2.c.d = 4;
alert(obj1.a); // 1
alert(obj2.a); // 3
alert(obj1.c.d); // 4
alert(obj2.c.d); // 4
2. Object.assign方法
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign(obj);
obj1.a = 3;
console.log(obj.a) // 3
3.使用扩展运算符实现
对于引用数据类型,扩展运算符实现的是浅拷贝。
4.用=赋值实现
let arr1=[0,1,2,3,4],
arr2=arr1;
console.log(arr1===arr2);
arr1[0]=1;
console.log(arr1,arr2);
深拷贝实现
1.递归实现
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
2. JSON.stringify和JSON.parse实现
var obj1 = {
a: 1,
b: {
c:2
}
}
var obj2 = JSON.stringify(JSON.parse(obj1)),
弊端:
1).如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式;
2).如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象;
3).如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
4).如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5).JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
6).如果对象中存在循环引用的情况也无法正确实现深拷贝;
3.通过jQuery的extend方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝
4.lodash函数库实现深拷贝
let result = _.cloneDeep(test)
5.Reflect法
// 代理法
function deepClone(obj) {
if (!isObject(obj)) {
throw new Error('obj 不是一个对象!')
}
let isArray = Array.isArray(obj)
let cloneObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(cloneObj).forEach(key => {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return cloneObj
}
6.Object.assign ,针对对象的value是基本类型
如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign({}, obj); // obj赋值给一个空{}
obj1.a = 3;
console.log(obj.a);// 1
7. 用slice实现对数组的深拷贝;用concat实现对数组的深拷贝
8 .使用扩展运算符实现(基本数据类型的拷贝)
// 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
// 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
var obj= {a: "1", b: "1", c: "2"}
var obj2= { ...obj, a: "5" }
9. 使用var newObj = Object.create(oldObj)
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
} else {
obj[i] = prop;
}
}
return obj;
}
网友评论