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