js中如何复制一个对象并获取其所有属性和属性对应的值

JavaScript06

js中如何复制一个对象并获取其所有属性和属性对应的值,第1张

如果是使用了  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的兼容性问题,都没有问题,考虑兼容性则按需垫片。生产环境其实还需要考虑其它类型的拷贝,一般直接使用辅助工具库。总而言之,按需拷贝);二是无法实现函数的拷贝。