资讯专栏INFORMATION COLUMN

js clone

diabloneo / 3190人阅读

摘要:克隆的概念浅克隆原始类型为值传递,对象类型仍为引用传递。深度克隆检验参数,如果不是对象直接返回原型链上继承过来的属性无法通过检测到,返回。方法用于将字符串解析为,可以任意转换生成的值及其属性,并返回值。

克隆的概念

浅克隆:原始类型为值传递,对象类型仍为引用传递。
深克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

浅克隆就是将栈内存中的引用复制一份,赋给一个新的变量,本质上两个指向堆内存中的同一地址,内容也相同,其中一个变化另一个内容也会变化(根本上改变的是同一个对象)。
深克隆就是创建一个新的空对象,开辟一块内存,然后将原对象中的数据全部复制过去,完全切断两个对象间的联系。
其实深拷贝和浅拷贝都是针对的引用类型,JS中的变量类型分为值类型(基本类型)和引用类型;对值类型进行复制操作会对值进行一份拷贝,而对引用类型赋值,则会进行地址的拷贝,最终两个变量指向同一份数据。

如果克隆对象是基本类型,我们直接赋值就可以了。
// 基本类型
var a = 1;
var b = a;
a = 2;
console.log(a, b); // 2, 1 ,a b指向不同的数据
如果不是基本类型,就有所不同了
// 引用类型指向同一份数据
var a = {c: 1};
var b = a;
a.c = 2;
console.log(a.c, b.c); // 2, 2 全是2,a b指向同一份数据
深克隆的方法
1)递归完成深克隆

通过递归去复制所有层级属性,为了保证对象的所有属性都被复制到,我们必须知道如果for循环以后,得到的元素仍是Object或者Array,那么需要再次循环。

//深度克隆
function deepClone(obj){
    // 检验参数,如果不是对象直接返回;原型链上继承过来的属性无法通过hasOwnProperty检测到,返回false。
    if(typeof obj != "object") return obj;
    var cloneObj=Object.prototype.toString.call(obj)=="[Object Array]" ? [] : {};
    for(var key in obj){
        // 判断是不是直系属性
        if(obj.hasOwnProperty(i)){
            // 判断obj子元素是否为对象,如果是, 递归调用;如果不是直接复制
            cloneObj[i]=typeof obj[i]=="object" ? deepClone(obj[i]) : obj[i];
        }
    }
    return cloneObj;
}
2)利用JSON——一行代码的深拷贝

cloneJSON内部也是使用递归的方式,原来是JSON.stringify内部做了循环引用的检测。

function cloneJSON(source) {
    return JSON.parse(JSON.stringify(source));
}

parse方法用于将字符串解析为 JSON,可以任意转换生成的值及其属性,并返回值。sretingify方法用于从一个对象中解析出json字符串。
什么意思呢?就是将一个对象先解析为json对象,然后再解析成object对象。变来变去顺道创建个对象完成复制。

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

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

相关文章

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

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

    fai1017 评论0 收藏0
  • js实现clone方法对各种数据类型进行复制

    摘要:对各种数据类型进行复制,最初的思想是利用判别数据类型后利用语句分别赋值,但是有个问题和返回的都是,所以又要细分为三种情况编写代码。其中,要判断一个对象为数组使用的是方法。 对各种数据类型进行复制,最初的思想是利用typeof判别数据类型后利用switch语句分别赋值,但是有个问题:null、Array和Object返回的都是‘object’,所以又要细分为三种情况编写代码。其中,要判断...

    CoffeX 评论0 收藏0
  • JS的深浅拷贝

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

    xiaoxiaozi 评论0 收藏0
  • 复习Javascript专题(四):js中的深浅拷贝

    摘要:基本数据类型的复制很简单,就是赋值操作,所以深浅拷贝也是针对,这类引用类型数据。它会抛弃对象的。另外,查资料过程中还看到这么一个词结构化克隆算法还有这一篇资料也有参考,也写得比较详细了的深浅拷贝 基本数据类型的复制很简单,就是赋值操作,所以深浅拷贝也是针对Object,Array这类引用类型数据。 浅拷贝对于字符串来说,是值的复制,而对于对象来说则是对对象地址的复制;而深拷贝的话,它不...

    MobService 评论0 收藏0
  • JS面向对象的程序设计之继承的实现-原型式继承和寄生式继承

    摘要:通过新增方法规范了原型式继承。适用场景在没有必要兴师动众地创建构造函数,而只想让一个对象与另外一个对象保持类似的情况下,原型式继承是完全可以胜任的。在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。 --前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感...

    lewinlee 评论0 收藏0
  • js中的深复制实现方法

    摘要:针对本话题,我在年月发布了新的文章深入剖析的深复制要实现深复制有很多办法,比如最简单的办法有上面这种方法好处是非常简单易用,但是坏处也显而易见,这会抛弃对象的,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成。 针对本话题,我在2015年5月发布了新的文章:深入剖析 JavaScript 的深复制 要实现深复制有很多办法,比如最简单的办法有: var...

    Alliot 评论0 收藏0

发表评论

0条评论

diabloneo

|高级讲师

TA的文章

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