专栏首页小码农学习笔记JavaScript 浅克隆与深克隆
原创

JavaScript 浅克隆与深克隆

浅克隆与深克隆

前言

浅克隆:浅克隆只是拷贝基本类型数据。对于引用类型数据,是将栈内存中的引用复制一份,赋给一个新的变量,本质上两个指向堆内存中的同一地址,内容也相同,其中一个变化另一个内容也会变化。

深克隆:就是创建一个新的空对象,开辟一块内存,然后将原对象中的数据全部复制过去,完全切断两个对象间的联系。新对象跟原对象不共享内存,修改新对象不会改到原对象。

区别:浅克隆和深克隆最大的区别就是对引用值的处理了,即浅克隆之后你改我也改,深克隆之后你改我不改

基本类型数据:保存在栈(stack)内存。

引用类型数据:保存在堆(heap)内存。

浅克隆概念

在浅克隆中,原始值的克隆没问题,只是值的拷贝,不会出现你改我改的问题。但是引用值的克隆,就会出现你改我也改的问题,因为浅层克隆的是地址,即指向的是同一空间。

深克隆概念

进行深克隆之后,对于引用值的克隆问题就能解决了,因为在深克隆之后,值各自独立,互不影响。

应用实例

浅克隆方法

  • 直接赋值
  • 手写(只拷贝对象或数组的第一层内容)
  • 数组的 Array.concat()
let oldArr = ['one', 'two', 'three'];
let newArr = oldArr.concat();
newArr.push('four');

console.log(oldArr); // ["one", "two", "three"]
console.log(newArr); // ["one", "two", "three", "four"]
  • 数组的 Array.slice()
let oldArr = ['one', 'two', 'three'];
let newArr = oldArr.slice();
newArr.push('four');

console.log(oldArr); // ["one", "two", "three"]
console.log(newArr); // ["one", "two", "three", "four"]
  • 对象的 Object.assign()
let oldObj = {
  a: 'one',
  b: 'two',
  c: 'three'
};

let newObj = Object.assign({}, oldObj);
newObj.d = 'four';
console.log(oldObj); // {a: "one", b: "two", c: "three"}
console.log(newObj); // {a: "one", b: "two", c: "three", d: "four"}
  • 数组和对象的解构赋值:
let oldObj = {
  a: 'one',
  b: 'two',
  c: 'three'
};

let newObj = {...oldObj};
newObj.d = 'four';
console.log(oldObj); // {a: "one", b: "two", c: "three"}
console.log(newObj); // {a: "one", b: "two", c: "three", d: "four"}

深克隆方法

  • 手写(层层拷贝对象或数组的每一层内容)
  • 将数组和对象转成 JSON 字符串再转回来(JSON.parse(JSON.stringify())):
    • JSON.stringify() 的局限性:对于 RegExp 类型和 Function 类型无法完全满足,而且不支持有循环引用的对象。(MDN)
let oldObj = {
  a: 'one',
  b: { bb: { bbb: 'two' }},
  c: ['three']
};

let newObj = JSON.parse(JSON.stringify(oldObj));
console.log(oldObj.b.bb === newObj.b.bb); // false
  • jQuery 有提供一个 $.extend 可以用来做深克隆:
let $ = require('jquery');
let oldObj = {
  a: 'one',
  b: { bb: { bbb: 'two' }},
  c: ['three']
};

let newObj = $.extend(true, {}, oldObj);
console.log(oldObj.b.bb === newObj.b.bb); // false
  • 函数库 Lodash,有提供 _.cloneDeep 用来做深克隆:
let _ = require('lodash');
let oldObj = {
  a: 'one',
  b: { bb: { bbb: 'two' }},
  c: ['three']
};

let newObj = _.cloneDeep(oldObj);
console.log(oldObj.b.bb === newObj.b.bb); // false

文章持续更新,本文 GitHub 前端修炼小册 已经收录,欢迎 Star。如对文章内容有不同见解,欢迎留言交流。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java | 浅克隆与深克隆

    克隆,即复制一个对象,该对象的属性与被复制的对象一致,如果不使用Object类中的clone方法实现克隆,可以自己new出一个对象,并对相应的属性进行数据,这样...

    一个优秀的废人
  • 1-02 深克隆与浅克隆

    jdk有个接口java.lang.Cloneable 这个接口是空接口,里面什么东西都没有 它的意思是实现了这个接口的类都是可以克隆的 真正实现了clon...

    suveng
  • Java的浅克隆与深克隆

    “克隆”一词总会让我们想起与生物学相关的科技医学技术,说的就是将动物的细胞取到后进行人工培育,从而培育出一个一模一样的动物(当然也包括人)。在编程界中...

    Java深度编程
  • 深克隆和浅克隆

    Java 集合中提供的拷贝构造函数只支持浅拷贝而不是深拷贝,这是因为集合中的拷贝构造函数是通过引用的复制来达到浅拷贝的。这意味着存储在原有集合和克隆集合中的对象...

    帅飞
  • 浅谈深克隆和浅克隆

    浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

    头皮阴都都
  • Java中的深克隆和浅克隆

    克隆的对象可能包含一些已经修改过的属性, 而new出来的对象的属性都还是初始化时候的值, 所以当需要一个新的对象来保存当前对象的"状态"时就要靠克隆了.

    烟草的香味
  • 【java开发系列】—— 深克隆和浅克隆

      Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中。那么什么是深克隆,什么是浅克隆呢。   【浅克隆】,通常只是对克隆的实例进行复制,但里面的...

    用户1154259
  • JAVA中的浅克隆和深克隆分析

    浅克隆(拷贝):复制一个对象的实例,但是这个对象中包含的其它的对象还是共用的。一般用super.clone()方法,clone的对象就是浅克隆。 深克隆(拷贝...

    冬天里的懒猫
  • Java对象的深克隆与浅克隆(对象复制)

    自定义了一个学生类,该类只有一个number字段。 新建了一个学生实例,然后将该值赋值给stu2实例。(Student stu2 = stu1;) 再看看打...

    JavaEdge
  • 克隆 JavaScript

    小丞同学
  • 如何复制一个java对象(浅克隆与深度克隆)

    在项目中,有时候有一些比较重要的对象经常被当作参数传来传去,和C语言的值传递不同,java语言的传递都是引用传递,在任何一个...

    天涯泪小武
  • 一文了解Java对象的克隆,深浅拷贝(克隆)

    在Java的Object类中,有一个方法名为clone(),直译过来就是克隆,核心概念就是复制对象并返回一个新的对象。

    程序员小强
  • 浅析克隆 顶

    一、在浅克隆中,如果原型对象的属性是值类型(如int,double,byte,boolean,char等),将复制一份给克隆对象;如果原型对象的属性是引用类型(...

    算法之名
  • 深度理解DOM拷贝clone()

    克隆节点是DOM的常见操作,jQuery提供一个clone方法,专门用于处理dom的克隆:

    小周sri的码农
  • 原型模式(Prototype)

    原型模式的结构 原型模式包含以下3个角色: •Prototype(抽象原型类) •ConcretePrototype(具体原型类) •Client(客户...

    happlyfox
  • 五分钟 掌握 原型模式

    大家好,我是老田,今天我给大家分享设计模式中的原型模式。用贴切的生活故事,以及真实项目场景来讲设计模式,最后用一句话来总结这个设计模式。

    田维常
  • 设计模式学习笔记之原型模式

    这是一篇学习笔记,内容很多是来源于网上的资料,按照自己学习情况进行的总结。 我的个人博客:海加尔金鹰

    海加尔金鹰
  • JavaScript 深拷贝性能分析

    作者:justjavac 链接:https://segmentfault.com/a/1190000013107871 如何在 JavaScript 中拷贝一个...

    程序员宝库
  • Web前端学习 第3章 JavaScript基础教程19 原始类型

    原始类型赋值给变量,遍历存储的是这个值本身,而你用类型赋值给变量,变量存储的是一个引用,这个引用会指向内存中的这个对象。

    学习猿地

扫码关注云+社区

领取腾讯云代金券