[整理]封装自己的until方法,实现对象的深拷贝

作者 likaiqiang 日期 2017-03-14
[整理]封装自己的until方法,实现对象的深拷贝
var obj = {
a:123,
b:456,
c:'asd'
}

如果要把obj赋值给另一个对象(obj2):

var obj2 = {};
obj2 = obj;

js中对象与数组是引用类型,这样做obj与obj2都指向了 {a:123,b:456,c:’asd},类似c语言中的指针,实际上给obj2.a赋值,obj.a的值也会跟着改变,这不是我们想要的。

那么如何实现对象的拷贝呢?

其实jquery有一个方法可以实现:

jQuery.extend( target [, object1 ] [, objectN ] );

不用jquery怎么实现呢?遍历对象,然后重新赋值嘛

cloneJson:function(json){
if(!isJson(json)) return json;//isJson()方法还没有
var newJson = {};
for(var n in json){
newJson[n] = json[n];
}
return newJson;
}

这种方法实现了对象的浅拷贝,那要如何实现一个对象的深拷贝呢?上面的方法用到了isJson方法,判断一个变量是不是对象、数组之类的常用方法,干脆封装成一个until对象吧。

var until = {
isArray:function(arr){
return arr instanceof Array;
},
isFunction:function(fuc){
return func instanceof Function;
},
isNumber:function(n){
return typeof n === 'number' || n instanceof Number;
},
isString:function(s){
return typeof s === 'string' || s instanceof String;
},
isJson:function(json){
return json.toString() === '[object Object]';
},
cloneArray:function(arr){
if(!this.isArray(arr)) return arr;
var newArray = [];
arr.forEach(function(item,index){
newArray[index] = item;
});
return newArray;
},
cloneJson:function(json){
if(!this.isJson(json)) return json;
var output = {};
for(var n in json){
if(this.isJson(json[n])){
output[n] = this.cloneJson(json[n]);
continue;
}
if(this.isArray(json[n])){
output[n] = this.cloneArray(json[n]);
continue;
}
output[n] = json[n];
}
return output;
}
}

你也许会有疑问,上面的isNumber,isString方法,为啥要那样判断呢?

我们通常会这样定义一个变量:var n1 = 123;var s1 = ‘asd’;

但是不可否认,也会有人这样定义一个变量:var n2 = new Number(123);var s2 = new String(‘asd’’);

所以判断一个变量是不是字符串或者数字,就必须那样判断。

cloneJson用到了递归,从而实现了对一个对象进行深拷贝,递归解释起来比较麻烦(其实是我语言表达能力不行),有问题可以联系我~~。