先看一个例子
var a = [1,2,3,4,5,6];
var b = a;
b.push('b');
console.log(a);
console.log(b);
输出结果:
[1, 2, 3, 4, 5, 6, "b"]
[1, 2, 3, 4, 5, 6, "b"]
是不是和想象中的完全不一样,我们改变的只是b数组,结果a数组也发生了变化;这就牵涉到今天的主题-------深拷贝
深拷贝(deepClone):对于一个引用类型,如果直接将他赋值给另一个变量,由于这两个引用指向同一个地址,这时改变其中的任何一个引用,另一个引用都会收到影响,当我们想复制一个对象并且切断这个对象的联系,就要使用深拷贝;
方案一:利用递归来解决:
//对元素的类型进行判断
function getType(obj) {
var toString = Object.prototype.toString();
var map = {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]' : 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Undefined]': 'undefined',
'[object Null]' : 'null',
'[object Object]' : 'object'
};
if( obj instanceof Element){
return 'element';
};
return map[toString.call(obj)];
}
//深度拷贝
function deepClone(data) {
var type = getType(data);
var obj;
if( type === 'array' ){
obj = [];
}else if( type === 'object' ){
obj = {};
}else {
return data;
}
if( type === 'array' ){
for( var i = 0;i < data.length;i++ ){
obj.push(deepClone(data[i]));
}
}else if( type === 'object' ){
for( var key in data ){
obj[key] = deepClone(data[key]);
}
}
return obj;
}
方案二:利用数组contact方法
var a = [1, 2];
var b = a.concat();
b.push(5);
console.log(a);
console.log(b);
contact方法连接数组返回的是一个新数组;
对象的拷贝:
var c = {c1: 1, c2: 2};
var d = Object.assign(new Object(), c);
d.d3 = 3;
console.log(c);
console.log(d);
方案三:利用数组的map方法
map()方法能够对数组进行遍历,并且回调函数中支持return返回值,不会影响原本的数组,只是吧原来的数组克隆了一份;
var ary = [12,23,24,42,1];
var res = ary.map(function (item,index,input) {
return item;
})
res.push(100);
console.log(res);//-->[12,23,24,42,1,100]; 原数组拷贝了一份,并进行了增加了长度
console.log(ary);//-->[12,23,24,42,1]; 原数组并未发生变化