资讯专栏INFORMATION COLUMN

js克隆一个对象,支持循环引用的克隆

fai1017 / 2042人阅读

摘要:判断参数是否为待判断的参数克隆一个对象要克隆的目标对象克隆节点,绑定事件的有问题,暂不处理克隆在当前作用域,在全局克隆其它对象,通过识别复制后的对象与原对象是否相同来决定传不传参数,像数组是不能传参数的使用防止对象重写了方法支持节点克隆

(function(){
  var toString=Object.prototype.toString,gObj={},cloneHelper=function(cache,item){
   /// helper for Utils.clone
   if ("object" == typeof item || Utils.isFunction(item)) {
    for (var i = cache.length - 2; i>=0; i -= 2) {
     if (cache[i] == item)
      return cache[i + 1]
    }
    cache.push(item, item = Utils.clone(item, cache))
   }
   return item 
  };
  window.Utils={
   isFunction:function(it){
    /// 判断参数是否为Function
    /// 待判断的参数
    /// 
    return toString.call(it)=="[object Function]";
   },
   clone:function(obj,cache){
    /// 克隆一个对象
    /// 要克隆的目标对象
    /// 
    cache || (cache = []);
    var clone,temp;
    if (!obj || (!Utils.isFunction(obj) && typeof obj != "object")) return o;
    else if (obj.cloneNode) return o.cloneNode(true);//克隆DOM节点,绑定事件的有问题,暂不处理
    else if (Utils.isFunction(obj)) clone = new Function("return " + obj)(); //克隆function eval在当前作用域,Funtion在全局
    else clone = (temp = obj.constructor, clone = new temp(obj.valueOf()), obj == clone) ? new temp() : clone; //克隆其它对象,通过识别复制后的对象与原对象是否相同来决定传不传参数,像数组是不能传参数的
    cache.push(obj,clone);
    for (temp in obj) if (gObj.hasOwnProperty.call(obj,temp)) clone[temp] = cloneHelper(cache,obj[temp]);//使用gObj.hasOwnProperty 防止对象obj重写了hasOwnProperty方法
    return clone
   }
 }());

支持节点克隆,对象克隆,同时也支持循环引用的对象克隆。

比如:

   var souceObj={

      childObj:{

     }

   };

  sourceObj.childObj.child=sourceObj;

这样一个循环引用的对象也可以正常克隆

cloneObj=Utils.clone(sourceObj);克隆后,同样保持与原来相同的引用关系

对于
var obj={};
var a={};

a.b=obj;
a.c=obj;

var d=Utils.clone(a);

在clone之前
a.b.f="123";
那么a.c也就有了一个f 为 "123";

但对于 clone之后的d 也有这功能

然而,每段代码或解决方案都有它的适用范围,以上代码也无法保证在所有浏览器中对任意对象克隆均能正常工作,您应当看懂理解代码,学以至用,而不是简单的把代码复制过去

以上代码在opera某些版本下克隆正则有问题,已满足大部分需求

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87846.html

相关文章

  • JavaScript 深拷贝

    摘要:深拷贝是一件看起来很简单的事情,但其实一点儿也不简单。我们也可以利用这个实现对象的深拷贝。而是利用之前已经拷贝好的值。深拷贝的详细的源码可以在这里查看。大功告成我们虽然的确解决了深拷贝的大部分问题。 js深拷贝是一件看起来很简单的事情,但其实一点儿也不简单。对于循环引用的问题还有一些内置数据类型的拷贝,如Map, Set, RegExp, Date, ArrayBuffer 和其他内置...

    zhangwang 评论0 收藏0
  • ES6时代,你真克隆对象吗(二)

    摘要:多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。比如,表达式会返回,因为属性得到的仅仅是构造函数,而且是可以被手动更改的,只是返回的构造函数的名字,它并不返回类名。 原文:ES6时代,你真的会克隆对象吗(二) 上一篇,我们从Symbol和是否可枚举以及属性描述符的角度分析了ES6下怎么浅拷贝一个对象,发表在掘金和segmentfault上(...

    BoYang 评论0 收藏0
  • js clone

    摘要:克隆的概念浅克隆原始类型为值传递,对象类型仍为引用传递。深度克隆检验参数,如果不是对象直接返回原型链上继承过来的属性无法通过检测到,返回。方法用于将字符串解析为,可以任意转换生成的值及其属性,并返回值。 克隆的概念 浅克隆:原始类型为值传递,对象类型仍为引用传递。深克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。 浅克隆就是将栈内存中...

    diabloneo 评论0 收藏0
  • 克隆

    摘要:结构化算法优于的地方优于的地方结构化克隆可以复制对象。的克隆粒度将会跟原始对象相同,并且复制出来相同的像素数据。企图去克隆节点同样会抛出异常。消息通道的传递是异步的,使用结构化克隆算法。 JavaScript 深拷贝性能分析(汉化版) JavaScript 深拷贝性能分析 Object.assign() Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。...

    freecode 评论0 收藏0
  • JS深浅拷贝

    摘要:引用类型之所以会出现深浅拷贝的问题,实质上是由于对基本类型和引用类型的处理不同。另外方法可以视为数组对象的浅拷贝。上面描述过的复杂问题依然存在,可以说是最简陋但是日常工作够用的深拷贝方式。 一直想梳理下工作中经常会用到的深拷贝的内容,然而遍览了许多的文章,却发现对深拷贝并没有一个通用的完美实现方式。因为对深拷贝的定义不同,实现时的edge case过多,在深拷贝的时候会出现循环引用等问...

    xiaoxiaozi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<