文档章节

javaScript中的对象深度克隆

呵呵闯
 呵呵闯
发布于 2016/06/11 19:09
字数 601
阅读 6
收藏 0

克隆分为两种,一种是浅度克隆,另一种为深度克隆。

以下定义看看就行

浅度克隆:原始类型为值传递,对象类型仍为引用传递。

深度克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

以下为干货:

对于原始类型,克隆表现为简单地值传递。对于对象类型,原理就是通过for..in..遍历原对象,将原对象中的属性赋值到新的对象中。但是由于原对象中的属性不仅只有一层,可能属性中仍包含着新的对象,如果只遍历一次,那么获得的新对象的属性与原对象的深层对象之间自然是仍保持着引用关系,导致新对象与原对象没有实现完全脱离。所以就出现了浅度克隆和深度克隆的区分。

在网上看到了三种方法来实现深度克隆,但其实原理都是使用递归进行深度复制,只是使用的判断数据类型的方法不同。

代码中要注意,判断对象类型时不能使用typeof,因为Array类型和Object类型都会返回Object,但是Array类型和Object类型又是不同的。

以下代码对于所有类型的克隆均可实现

第一种方法:

//返回传递给他的任意对象的类
function isClass(o){
    if(o===null) return "Null";
    if(o===undefined) return "Undefined";
    return Object.prototype.toString.call(o).slice(8,-1);
}
//深度克隆
function deepClone(obj){
    var result,oClass=isClass(obj);
        //确定result的类型
    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 clone(obj) {
   var o;
   if (typeof obj == "object") {
       if (obj === null) {
           o = null;
       } else {
           if (obj instanceof Array) {
               o = [];
               for (var i = 0, len = obj.length; i < len; i++) {
                   o.push(clone(obj[i]));
               }
           } else {
               o = {};
               for (var j in obj) {
                   o[j] = clone(obj[j]);
               }
           }
       }
   } else {
       o = obj;
   }
   return o;
}

第三种方法:仅限于深度克隆对象

Object.prototype.Clone = function(){
  var objClone;
  if (this.constructor == Object){
    objClone = new this.constructor();
  }else{
    objClone = new this.constructor(this.valueOf());
  }
  for(var key in this){
    if ( objClone[key] != this[key] ){
    if ( typeof(this[key]) == 'object' ){
      objClone[key] = this[key].Clone();
    }else{
      objClone[key] = this[key];
    }
  }
}
  objClone.toString = this.toString;
  objClone.valueOf = this.valueOf;
  return objClone;
}

 

© 著作权归作者所有

共有 人打赏支持
呵呵闯
粉丝 3
博文 67
码字总数 15949
作品 0
深圳
程序员
Object.assign()

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign 说明 Object.assign()方法将所有可枚举属性的值从一个或多个源对象复制到目标对象,然后返...

莫问今朝乄
2017/12/03
0
0
js笔记十七之DOM操作-增删改

DOM的赠删改 增 真是项目中, 我们会在js中动态创建一些html标签, 然后把其增加到页面中 document.createElement 在js中动态创建一个html标签 appendChild 容器.appendChild(新元素) 把当前创...

uplyw
05/11
0
0
JS中的prototype的一些理解

JS中的phototype是JS中比较难理解的一个部分 本文基于下面几个知识点: 1 原型法设计模式 在.Net中可以使用clone()来实现原型法 原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是...

Doublec
2015/05/14
0
0
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话):   有人说拖延症是一个绝症,哎呀治不好了。先不说这是一个每个人都多多少少会有的,也不管它究竟对...

grootzhang
2016/09/24
0
0
【zepto学习笔记02】零碎点

前言 上次我们看了zepto的选择器方面的东西,其实zepto简单很大程度是因为他用了最新的检索器querySelectorAll, 今天我们来学习下zepto的一些零碎点的地方吧,主要根据zepto官方文档顺序来 ...

panpanhtai
2014/07/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

70.shell的函数 数组 告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析 20.16/20.17 shell中的函数: ~1. 函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段...

王鑫linux
今天
2
0
分布式框架spring-session实现session一致性使用问题

前言:项目中使用到spring-session来缓存用户信息,保证服务之间session一致性,但是获取session信息为什么不能再服务层获取? 一、spring-session实现session一致性方式 用户每一次请求都会...

WALK_MAN
今天
5
0
C++ yield()与sleep_for()

C++11 标准库提供了yield()和sleep_for()两个方法。 (1)std::this_thread::yield(): 线程调用该方法时,主动让出CPU,并且不参与CPU的本次调度,从而让其他线程有机会运行。在后续的调度周...

yepanl
今天
4
0
Java并发编程实战(chapter_3)(线程池ThreadPoolExecutor源码分析)

这个系列一直没再写,很多原因,中间经历了换工作,熟悉项目,熟悉新团队等等一系列的事情。并发课题对于Java来说是一个又重要又难的一大块,除非气定神闲、精力满满,否则我本身是不敢随便写...

心中的理想乡
今天
33
0
shell学习之获取用户的输入命令read

在运行脚本的时候,命令行参数是可以传入参数,还有就是在脚本运行过程中需要用户输入参数,比如你想要在脚本运行时问个问题,并等待运行脚本的人来回答。bash shell为此提 供了read命令。 ...

woshixin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部