精华内容
下载资源
问答
  • 关于对象的深拷贝和浅拷贝,通俗点讲,对象B复制对象A,当改变B的时候,A跟着变,那么就是浅拷贝,如果A不变,两者相互不影响,那么就是深拷贝。要理解对象的深拷贝和浅拷贝,得先理解 js 中值类型和引用类型在内存...

    JS对象之深拷贝和浅拷贝

    关于对象的深拷贝和浅拷贝,通俗点讲,对象B复制对象A,当改变B的时候,A跟着变,那么就是浅拷贝,如果A不变,两者相互不影响,那么就是深拷贝。要理解对象的深拷贝和浅拷贝,得先理解 js 中值类型和引用类型在内存中的存储方式,可以看看这篇文章

    数据类型

    值类型(Stack):

    包括 Number, String, Boolean, Null, Undefined, Symbol(ES6),拷贝操作均属于深拷贝,因为它们操作的是实际值。

    引用类型(Heap):

    包括 Array, Object, Function 等对象,拷贝操作可以是浅拷贝,也可以是深拷贝。接下来通过示例来揭开深拷贝和浅拷贝的神秘面纱。

    浅拷贝

    值类型拷贝都是深拷贝(number, string, boolean, null, undefined, symbol)。

    let a = "hello";
    let b = a;
    b = "world";
    console.log(a);
    
    // hello
    

    引用类型 array 浅拷贝

    let arrA = [1, 2, 3, 4, 5];
    let arrB = arrA;
    arrB.push(6);
    console.log(arrA);
    
    // [1, 2, 3, 4, 5, 6]  A 同时发生了变化
    
    

    引用类型 object 浅拷贝

    let objA = { name: "zhangsan", age: 30, course: { chinese: 100 } };
    let objB = objA;
    objB.name = "lisi";
    objB.course.chinese = 89;
    console.log(JSON.stringify(objA));
    
    // {"name":"lisi","age":30,"course":{"chinese":89}}
    
    

    深拷贝

    单个层级

    对于单个层级的对象,使用 ES6 语法块 { ... x} 或者 Object.assign() 即可实现深拷贝。对于嵌套对象,使用这两个方法就“歇菜了”。

    let objA = { name: "zhangsan", age: 30 };
    let objB = {...objA};
    // let objB = Object.assign({},objA);
    objB.name = "lisi";
    console.log(objA);
    
    // {name: "zhangsan", age: 30} 
    

    浅拷贝例子

    let objA = { name: "zhangsan", age: 30, course: { chinese: 100 } };
    let objB = {...objA};  // 不好用了吧
    objB.name = "lisi";
    objB.course.chinese = 89;
    
    // {"name":"zhangsan","age":30,"course":{"chinese":89}}
    

    嵌套对象

    嵌套对象,比较“暴力”的深拷贝方法是使用 JSON.parse(JSON.stringify(objA))

    let objA = { name: "zhangsan", age: 30, course: { chinese: 100 } };
    let objB = JSON.parse(JSON.stringify(objA));
    
    objB.name = "lisi";
    objB.course.chinese = 89;
    
    // {"name":"zhangsan","age":30,"course":{"chinese":100}}
    

    然而这种方式显得不够优雅,我们来尝试手写一个 工具方法 DeepClone 实现深拷贝吧。

    手写DeepClone

    直接上代码,利用递归的方式实现对象的层层遍历。下面的代码并不完善,例如没有考虑对 date,file,map, set等对象的拷贝。经典库 loadash 提供了 cloneDeep 来实现深拷贝,阅读其源码,发现对10多种常见的对象做了处理,已经较为完善。

    function deepClone(targetObj) {
    	let type = Object.prototype.toString.call(targetObj);
    	let newObj;
    	if (type === "[object Object]") {
    	  newObj = {};
    	} else if (type === "[object Array]") {
    	  newObj = [];
    	} else {
    	  return targetObj;
    	}
    	for(key in targetObj) {
    	    let value = targetObj[key];
    	    newObj[key] = deepClone(value);
    	}
    	return newObj;
    }
    
    
    展开全文
  • es6 对象深拷贝和浅拷贝

    万次阅读 2018-10-24 09:42:21
    简介:在项目中,为了不影响原有数据,在操作数据时,经常需要深拷贝一个对象,在开发过程中,实践得出。 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 ...

    简介:在项目中,为了不影响原有数据,在操作数据时,经常需要深拷贝一个对象,在开发过程中,实践得出。

    • Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
    
    
    const object1 = {
      a: 1,
      b: 2,
      c: 3
    };
    
    const object2 = Object.assign({c: 4, d: 5}, object1);
    console.log(object2);
    
    > Object { c: 3, d: 5, a: 1, b: 2 }
    
    这是浅拷贝,返回的不是一个新对象,而是把一个或多个源对象添加到目标对象
    
    
    • 结构赋值
    ​
    
    
    let object1 = {
      a: 1,
      b: 2,
      c: 3
    };
    
    let object2 = {...object1};
    object1.a=11;
    
    console.log(object2);
    > Object { a: 1, b: 2, c: 3 }
    
    仿佛好像深拷贝,但是如果object1嵌套了一层对象,就发现会互相影响了。
    let object1 = {
      a: 1,
      b: 2,
      c: {a:1,b:2}
    };
     
    let object2 = {...object1};
    object1.c.a=11;
    
    > Object {a: 1, b: 2, c: {a: 11, b: 2}}
    
    所以这也是浅拷贝
    
    
    ​
    • 最简单的深拷贝(JSON.stringify() 和JSON.parse())
    • 先把对象使用JSON.stringify()转为字符串,再赋值给另外一个变量,然后使用JSON.parse()转回来即可。
    • let object1 = {
        a: 1,
        b: 2,
        c: 3
      };
      
      let object2 =JSON.parse( JSON.stringify(object1));
      object2.a=11;
      
      console.log(object1,object2);
      
      > Object { a: 1, b: 2, c: 3 } Object { a: 11, b: 2, c: 3 }

       

    展开全文
  • 浅拷贝 概念:浅拷贝的意思就是只复制引用,而未复制真正的值。仍指向同一个地址,修改时原对象...4.对象浅拷贝 - Object.assign()。 5.对象浅拷贝 - 扩展运算符 函数封装 //对象及数组浅拷贝函数封装 functi...

    浅拷贝

    概念:浅拷贝的意思就是只复制引用,而未复制真正的值。仍指向同一个地址,修改时原对象也会受到影响

    方法:

    1.利用 = 赋值操作符实现浅拷贝。

    2.数组的浅拷贝一般使用 slice、concat。

    3.数组浅拷贝 - 遍历 。

    4.对象浅拷贝 - Object.assign()。

    5.对象浅拷贝 - 扩展运算符

    函数封装

    //对象及数组浅拷贝函数封装
        function shallowCopy(objOrArr){
            var type = objOrArr instanceof Array ? 'arr' : 'obj'
            var newObjOrArr = objOrArr instanceof Array ? [] : {}
            if(type === 'arr'){
                newObjOrArr=[].concat(objOrArr)
            }else{
              for(var key in objOrArr){
                  if(objOrArr.hasOwnProperty(key)){
                        newObjOrArr[key]= objOrArr[key]
                  }
              }
            }
    
            return newObjOrArr
        }

    深拷贝

    概念:深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。修改时原对象不再受到任何影响

    方法:

    1.利用 JSON 对象中的 parsestringify

    2.利用递归来实现每一层都重新创建对象并赋值。

    函数封装

    //对象及数组深拷贝函数封装
            function deepCopy(objOrArr) {
                var type = objOrArr instanceof Array ? 'arr' : 'obj'
                var newObjOrArr = objOrArr instanceof Array ? [] : {}
                if (type === 'arr') {
                    newObjOrArr = JSON.parse(JSON.stringify(objOrArr))
                } else {
                    for (var key in objOrArr) {
                        if (objOrArr.hasOwnProperty(key)) {
                            newObjOrArr[key] = typeof objOrArr[key] === 'object' ? deepCopy(objOrArr[key]) : objOrArr[key]
                        }
                    }
                }
    
                return newObjOrArr
            }

     

     

     

     

    展开全文
  • 想必刚接触javascript的同学应该遇到过一个问题,将一个对象...对象拷贝分为深拷贝和浅拷贝,而浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,简单类型Undefined,Null,...

     

    想必刚接触javascript的同学应该遇到过一个问题,将一个对象复制一份用一个新的变量来存起来,然后再来操作这个新变量的时候,奇怪的事情发生了,我只修改了副本,为什么原对象却跟着改变了????

    这就涉及到了对象拷贝相关的知识点了。

    对象拷贝分为深拷贝和浅拷贝,而浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,简单类型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 则是存入桟中,只用一个指针来引用值),如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正地对对象的拷贝。


    浅拷贝:

    浅拷贝的意思就是只复制引用(指针),而未复制真正的值。

    比如我们在日常开发中用得最多的就是 通过 = 来进行赋值,这就实现了一个浅拷贝。

    深拷贝:

    深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。

    只要进行了深拷贝,它们老死不相往来,谁也不会影响谁。

    目前实现深拷贝的方法不多,主要是两种:

    1.利用 JSON 对象中的 parse 和 stringify

    JSON.parse 是将一个 JSON 字符串转成一个 JavaScript 值或对象。

    很好理解吧,就是 JavaScript 值和 JSON 字符串的相互转换。

    它能实现深拷贝呢?我们来试试。

    const originArray = [1,2,3,4,5];
    
    const cloneArray = JSON.parse(JSON.stringify(originArray));
    
    console.log(cloneArray === originArray); // false

    确实是深拷贝,也很方便。但是,这个方法只能适用于一些简单的情况。 比如下面这样的一个对象就不适用:

    const originObj = {
      name:'axuebin',
      sayHello:function(){
        console.log('Hello World');
      }
    }
    console.log(originObj); // {name: "axuebin", sayHello: ƒ}
    const cloneObj = JSON.parse(JSON.stringify(originObj));
    console.log(cloneObj); // {name: "axuebin"}

     

    发现在 cloneObj 中,有属性丢失了。。。那是为什么呢?

    undefinedfunctionsymbol 会在转换过程中被忽略。。。

    总结:如果对象中含有一个函数时(很常见),就不能用这个方法进行深拷贝。

    2.利用递归来实现每一层都重新创建对象并赋值

    递归的思想就很简单了,就是对每一层的数据都实现一次 创建对象->对象赋值 的操作,简单粗暴上代码:

    function deepClone(source){
      const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
      for(let keys in source){ // 遍历目标
        if(source.hasOwnProperty(keys)){
          if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
            targetObj[keys] = source[keys].constructor === Array ? [] : {};
            targetObj[keys] = deepClone(source[keys]);
          }else{ // 如果不是,就直接赋值
            targetObj[keys] = source[keys];
          }
        }
      }
      return targetObj;
    }

     我们来试试:

    const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};
    
    const cloneObj = deepClone(originObj);
    
    console.log(cloneObj === originObj); // false

     

    结果是完全没有问题的,下面再来试试带有函数的:

    const originObj = {
      name:'axuebin',
      sayHello:function(){
        console.log('Hello World');
      }
    }
    console.log(originObj); // {name: "axuebin", sayHello: ƒ}
    const cloneObj = deepClone(originObj);
    console.log(originObj===cloneObj); // false

    也是可以搞定的!参考于https://www.cnblogs.com/dabingqi/p/8502932.html

    展开全文
  • Js中对象深拷贝和浅拷贝

    千次阅读 2018-07-10 18:19:44
    浅拷贝仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么深拷贝出来的对象也会相应改变。一、对象引用对象引用容易理解,直接赋值,修改复制后的数组,原对象会随之改变。//对象引用 var boy = { age:18...
  • java复制Map 对象(深拷贝和浅拷贝)

    千次阅读 2020-09-04 00:04:25
    2. 通过 putAll()方法能实现浅拷贝和深拷贝, 使用Map对象只能实现浅拷贝 public static void main(String[] args) { // Map只能实现浅拷贝,paramMap中的内容发生变化,paramMap2中的内容亦同步发生变化 Map<...
  • dict2 = dict1.copy() #浅拷贝 拷贝一级对象,但是如果字典里有个列表,改变dict1中这个列表的值的时候,dict2相应改变,可以自己递归实现深拷贝 import copy dict2 = copy.deepcopy(dict1)#深拷贝所有级别的对象都...
  • JavaScript中有两种类型的对象拷贝:浅拷贝(Shallow Copy)、深拷贝(Deep Copy)。 最根本的区别在于是否是真正获取了一个对象的复制实体,而不是引用。 浅拷贝 —-只是拷贝了基本类型的数据,而引用类型数据,复制...
  • package ioc; /** * @Author:zhuo * @Date:2018/4/30 15:46 * */ ...public class VarCopyDemo { public static void main(String[] args) { ...\n********下面是浅拷贝内容********\n");...
  • Java中分为深拷贝和浅拷贝; BeanA 对象如下: public class BeanA { private String str1, str2; private List<BeanB> beanBList; } 如需浅拷贝,则需实现Serializable 接口,并重写 clone 方法,...
  • 深拷贝和浅拷贝

    万次阅读 多人点赞 2019-05-12 17:28:52
    深拷贝和浅拷贝的知识涉及到堆栈的概念。 堆栈的概念: 基本类型: 名值存储在栈内存中,例如: let a = 1; 引用类型: 名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值; ...
  • 深拷贝和浅拷贝区别是什么?

    万次阅读 多人点赞 2019-06-18 15:44:47
    拷贝和浅拷贝区别是什么? 复制一个 Java 对象 浅拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象深拷贝:复制基本类型的属性;...
  • 今天大家分享一个关于实现复制一个对象的方法 首先我们需要了解一个知识点,那就是es6的新方法 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 语法:...
  • Map拷贝 关于对象深拷贝 浅拷贝的问题 概念 浅复制:则是只复制对象的引用,两个引用仍然指向同一个对象,在内存中占用同一块内存。被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然...
  • iOS深拷贝和浅拷贝

    千次阅读 2018-08-01 16:53:35
    一:概念 浅拷贝:指针拷贝,不会创建一个新的对象。浅拷贝简单点说就是对内存地址的复制,让目标对象指针和源对象指针指向同一片内存空间...二:各种类型的对象深拷贝浅拷贝 1.非容器类对象(比如像NSString,N...
  • Js复制对象/克隆对象 Js浅拷贝与深拷贝 浅拷贝和深拷贝的实现方法 前言 学习Js克隆一个对象,作为准备工作,需要理解Js中的数据类型和按值传递:Js中的数据类型和按值传递 浅拷贝最后两种方法不理解的话,可以读es5...
  • 引用拷贝和对象拷贝的不同之处在于,引用拷贝只会生成一个新的对象引用地址,但两个地址其最终指向的还是同一个对象对象拷贝:这种方式会重新生成一个新的对象,生成的新对象与原来的对象没有任何关联。 1、...
  • Java深入理解深拷贝和浅拷贝区别

    万次阅读 多人点赞 2019-02-13 23:31:47
    创建一个指向对象的引用变量的拷贝。 Teacher teacher = new Teacher("Taylor",26); Teacher otherteacher = teacher; System.out.println(teacher); System.out.println(otherteacher); 输出结果: blog...
  • JavaScript对象浅拷贝和深拷贝

    千次阅读 2020-12-03 15:51:32
    JavaScript对象浅拷贝和深拷贝1. 基本概念2. 浅拷贝3. 深拷贝3.1 深拷贝JSON方法3.2 深拷贝手写递归方法4, 1. 基本概念 对象是引用类型,在声明引用类型的时候,对象是存储在堆内存中的,而js不能直接操作内存,...
  • 1、首先理解一下“深拷贝浅拷贝”的区别: 浅拷贝:a = b;//ab中存的是相同的地址,该地址指向堆内存中相同的地方,即ab就是一...(1)数组和对象浅拷贝一样 ,简单的赋值操作 var b = a; 如数组的浅...
  • 【iOS】自定义对象深拷贝浅拷贝

    千次阅读 2015-05-20 21:28:32
    其中遇到的问题不少,关于object-c的学习就不再赘述,其中的一个问题我觉得在这里记一笔,对今后有帮助——自定义对象深拷贝浅拷贝。 我有一个CCard类,用一个NSMutableArray来保存,我打算在牌堆中随机挑选6张...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 71,451
精华内容 28,580
关键字:

对象的深拷贝和浅拷贝