深拷贝
// 1利用 递归 来实现深复制,对属性中所有引用类型的值,遍历到是基本类型的值为止。
function deepClone(source){
if(!source && typeof source !== 'object'){
throw new Error('error arguments', 'shallowClone');
}
var targetObj = Array.isArray(source) ? [] : {};
for(var keys in source){
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === 'object'){
targetObj[keys] = deepClone(source[keys]); //递归
}else{
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
// 数组
// Array 的 slice 和 concat 方法 和 jQuery 中的 extend 复制方法
// ,他们都会复制第一层的值,对于 第一层 的值都是 深拷贝
// ,而到 第二层 的时候 Array 的 slice 和 concat 方法就是 复制引用 ,
// jQuery 中的 extend 复制方法 则 取决于 你的 第一个参数, 也就是是否进行递归复制。
// 所谓第一层 就是 key 所对应的 value 值是基本数据类型,也就像上面栗子中的name、age,
// 而对于 value 值是引用类型 则为第二层,也就像上面栗子中的 company。
var a = [1,2,3];
var b = a.concat(); //concat
console.log(b === a);
a[0] = 4;
console.log(a);
console.log(b);
var a = [[1,2,3],4,5];
var b = a.slice();
console.log(a === b);
a[0][0] = 6;
console.log(a);
console.log(b);
// 所以你要记住的是 Array的 slice 和 concat 方法 并不是 真正的深拷贝,
// 他们其实是披着羊(qian)皮(kao)的(bei)狼。
// 2、 jQuery中的 extend 复制方法
// 可以用来扩展对象,这个方法可以传入一个参数:deep(true or false)
// ,表示是否执行深复制(如果是深复制则会执行递归复制)。
var obj = {name:'xixi',age:20,company : { name : '腾讯', address : '深圳'} };
var obj_extend = $.extend(true,{}, obj); //extend方法,第一个参数为true,为深拷贝,为false,或者没有为浅拷贝。
// 3、JSON 对象的 parse 和 stringify
// JOSN 对象中的 stringify 可以把一个 js 对象序列化为一个 JSON 字符串,parse 可以把 JSON 字符串反序列化为一个 js 对象,这两个方法实现的是深拷贝。
// 栗子:
var obj = {name:'xixi',age:20,company : { name : '腾讯', address : '深圳'} };
var obj_json = JSON.parse(JSON.stringify(obj));
console.log(obj === obj_json);
obj.company.name = "ali";
obj.name = "hei";
console.log(obj);
console.log(obj_json);