如果是使用了 JQ EXTJS 的话本身就有 对象克隆的 函数库可以使用 如 extjs 使用
ext.ux.util.clone()
没有用这些的话 可以自己写一个 克隆函数 网上有资源 比如
function deepClone(obj){ var result={},oClass=isClass(obj)// if(oClass==="Object"){
// result={}
// }else if(oClass==="Array"){
// result=[]
// }else{
// return obj
// }
for(key in obj){
var copy=obj[key]
if(isClass(copy)=="Object"){
result[key]=arguments.callee(copy)
}else if(isClass(copy)=="Array"){
result[key]=arguments.callee(copy)
}else{
result[key]=obj[key]
}
}
return result
}
function isClass(o){
if(o===null) return "Null"
if(o===undefined) return "Undefined"
return Object.prototype.toString.call(o).slice(8,-1)
}
或者参考 extjs 的方法
function(o) {if(!o || 'object' !== typeof o) { return o }
if('function' === typeof o.clone) { return o.clone() }
var c = '[object array]' === object.prototype.tostring.call(o) ? [] : {}
var p, v
for(p in o) {
if(o.hasownproperty(p)) { v = o[p]
if(v && 'object' === typeof v) {
c[p] = ext.ux.util.clone(v)
} else {
c[p] = v
}
}
}
return c}
对象类型在赋值的过程中实际上是复制了地址,从而导致了其中一方被改变其他也都被改变的情况,在开发中我们通常不希望出现这样的问题,这里可以使用浅拷贝来解决这个情况。
首先我们可以通过Object.assign来实现浅拷贝,该函数只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,即为浅拷贝而不是深拷贝。
以下为Object.assign浅拷贝的简单实现:
还可以通过展开运算符...来实现浅拷贝:
但是,浅拷贝只解决了第一层的问题,如果对象下还有对象的话,那么又回到最开始的问题了,第二层的对象拷贝过来的只是地址,两者享有相同的地址,这时就需要用到深拷贝了。
我们通常使用JSON.parse(JSON.stringify(object))来解决:
但是该方法具有以下局限性:
遇到函数、undefined和symbol时,会直接忽略掉他们,该对象不能正常的序列化,此时我们需要实现一个更为完善的深拷贝。
小结:以上深拷贝的方法依然只是较为简易的,要想实现一个比较完美的深拷贝其实是很困难的,需要我们考虑很多种边界情况,比如原型链如何处理、DOM如何处理等。该deepClone函数就有两个较为明显的问题,一是没有解决对象的循环引用的问题(参考方案:用弱映射做一个哈希表,存储原对象,若缓存命中,则过滤本次拷贝,直接使用记忆化数据,否则惰性拷贝。一般不是为了解决IE的兼容性问题,都没有问题,考虑兼容性则按需垫片。生产环境其实还需要考虑其它类型的拷贝,一般直接使用辅助工具库。总而言之,按需拷贝);二是无法实现函数的拷贝。