在JAVAScript中数据类型分为两种,一种是原始数据类型,另外一种就是引用数据类型。
数据类型
原始数据类型:其中存储的是对象的实际地址。
unmber
、string
、boolean
和两个特殊的null
、underfined
。
引用数据类型:其中存储的是对象的引用地址。
array
、function
、object
。
存在的问题
对于原始数据类型而言,通过简单的赋值操作,就可以实现深度克隆。例子:
var a = 1;
var b = a;
a = 10;
console.log(b); // 1
var a = 'hello';
var b = a;
a = 'world';
console.log(b); // hello
var a = true;
var b = a;
a = false;
console.log(b); // true
在上面可以看到把
a
赋值给b
,b
改变之后完全没有影响到a
。
但是引用类型不一样,它存储的是对象的引用地址。就会导致以下的问题产生
//简单的使用数组进行实例
var a = [1,2,3];
var b = a;
console.log(b); //[1,2,3]
b.push(4);
console.log(b); //[1,2,3,4]
console.log(a); //[1,2,3,4]
从以上的代码可以看到把
a
的值赋给了b
,b
改变之后影响到了a
。这是为什么呢?
由于引用类型数据存储在应用地址内存中,因此赋值复制的也是这一块地址,因此相当于两个数组对象引用了一块数据地址,所以对a或者b的任何操作或者改变都会体现在对象中。
为了避免这种情况,引入了深度克隆。
解决方案:深度克隆
function clone(obj){
var buf;
if(obj instanceof Array){
buf = [];
var i = obj.length;
while(i--){
buf[i] = clone(obj[i]);
}
return buf;
}
else if(obj instanceof Object){
buf = {};
for(var k in obj){
buf[k] = clone(obj[k]);
}
return buf;
}
else{
return obj;
}
}
或者精简的写法(递归)
function clone(obj) {
var o = obj instanceof Array ? [] : {};
for(var k in obj)
o[k] = typeof obj[k] === Object ? clone(obj[k]) : obj[k];
return o;
}
var a = [[1, 2, 3], [4, 5, 6, 7]];
var b = clone(a);
console.log(b);