深拷贝: 深拷贝即创建新的内存地址保存值(互不影响)
浅拷贝: 共用同一内存地址,你改变我也跟着变
// Array.prototype.concat 深拷贝用法
var arr1 = ["1","2","3"];
var arr2 = arr1.slice(0);
arr2[1] = "9";
console.log("数组的原始值:" + arr1 ); // ["1","2","3"]
console.log("数组的新值:" + arr2 ); // ["1","9","3"]
//Array.prototype.slice 深拷贝用法
var arr1 = ["1","2","3"];
var arr2 = arr1.concat();
arr2[1] = "9";
console.log("数组的原始值:" + arr1 ); // ["1","2","3"]
console.log("数组的新值:" + arr2 ); // ["1","9","3"]
// Array.prototype.concat 浅拷贝用法
var arr1 = [{"name":"weifeng"},{"name":"boy"}]; //原数组
var arr2 = [].concat(arr1); //拷贝数组
arr1[1].name="girl";
console.log(arr1); // [{"name":"weifeng"},{"name":"girl"}]
console.log(arr2); //[{"name":"weifeng"},{"name":"girl"}]
// Array.prototype.slice 浅拷贝用法
var a1=[["1","2","3"],"2","3"] , a2;
a2=a1.slice(0);
a1[0][0]=0; //改变a1第一个元素中的第一个元素
console.log(a2[0][0]); //影响到了a2
var b1=[["1","2","3"],"2","3"] , b2;
b2=b1.slice(0);
b1[0][0]=0; //改变a1第一个元素中的第一个元素
console.log(b2[0][0]); //影响到了a2
总结:slice和concat两个方法,可深拷贝可浅拷贝,取决于拷贝的是基本数据还是引用数据(适用于不包含引用对象的一维数组的深拷贝)
// Object.assign() 用法
// (1)合并多个对象
const obj1 = { name: 'kattes',age: 24}
const obj2 = { address: '四川成都', hobby: 'code' }
const obj3 = { workingYears: 5}
const obj = Object.assign(obj1, obj2, obj3)
console.log(obj) //{ name: 'kattes', age: 24, address: '四川成都', hobby: 'code', workingYears: 5}
// (2)克隆对象(浅)
const obj = { name: 'kattes' ,age: 24}
const obj1 = Object.assign({},obj)
console.log(obj1) //{ name: 'kattes' ,age: 24}
// (3)为对象添加多个方法
Object.assign(classOne.prototype, {
method1(arg1, arg2) {},
method2() {}
});
// js原始方法
classOne.prototype.method1 = function (arg1, arg2) {};
classOne.prototype.method2 = function () {};
总结: Object.assign是浅拷贝(只会深拷贝一层,不会递归拷贝,所以依然是浅拷贝,但此方法如果用于简单的基本数据拷贝,则就相当于深拷贝)
// JSON.parse(JSON.stringify(obj))
let obj = {
a: 123,
b: {
c: 456,
d: {
e: 789
}
}
};
let copy = JSON.parse(JSON.stringify(obj));
// 对obj对象无论怎么修改,都不会影响到copy对象
obj.b.c = 'hello';
obj.b.d.e = 'world';
console.log(copy); // {a: 123, b: {c: 456, d: {e: 789}}}
总结: JSON.parse(JSON.stringify()) 此方法适用于简单值、对象和数组三种类型的深拷贝,不适用于变量、函数或对象实例的拷贝 (函数会丢失,原型链会丢失)
总结如下两种拷贝函数,如有需要,请白嫖拿走:(不适用于复杂的场景)
// 深拷贝 复制所有的属性
function deepClone(source){
const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
for(let keys in source){ // 遍历目标
if(source.hasOwnProperty(keys)){//hasOwnProperty方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性
if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
}else{ // 如果不是,就直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
// 浅拷贝 复制所有属性
function shallowCopy(obj) {
var copy = {};
// 只复制可遍历的属性
for (key in obj) {
// 只复制本身拥有的属性
if (obj.hasOwnProperty(key)) {
copy[key] = obj[key];
}
}
return copy;
}