zoukankan      html  css  js  c++  java
  • 深浅拷贝

    1. 浅拷贝

    js的数据类型,分为基本类型和引用类型

    js基本类型:Number、String、Boolean, 其传值方式是按照按值传递的方式

    var num1 = 1;
    var num2 = num1;
    num2 = 2;
    此时的num1的值不受影响,仍为1;

    引用类型是按引用传值

    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = obj1;
    obj2.b = 100;
    console.log(obj1);
    // { a: 10, b: 100, c: 30 } <-- b 被改到了
    console.log(obj2);
    // { a: 10, b: 100, c: 30 }

    上面赋值,是引用赋值,是将 obj1 的地址复制给 obj2, obj1 和 obj2 指向的是同一个内存区域。因此对任何一个修改,其实修改的都是同一个对象,这就是所谓的浅拷贝。

    浅拷贝的几种方式

    1. Object.assign()

      可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

    2. lodash的clone方法

    3. ...操作符

      let obj1 = { name: 'Kobe', address:{x:100,y:100}}
      let obj2= {... obj1}
      obj1.address.x = 200;
      obj1.name = 'wade'
      console.log('obj2',obj2) // obj2 { name: 'Kobe', address: { x: 200, y: 100 } }
      
    4. Array.prototype.concat

      let arr = [1,2,3]; let arr2 = [4,5,6];let arr3 = arr.concat(arr2)

      let arr = [1, 3, {
          username: 'kobe'
          }];
      let arr2 = arr.concat();    
      arr2[2].username = 'wade';
      console.log(arr);
      
    5. Array.prototype.slice

      let arr = [1, 3, {
          username: ' kobe'
          }];
      let arr3 = arr.slice();
      arr3[2].username = 'wade'
      console.log(arr); // [ 1, 3, { username: 'wade' } ]

    2. 深拷贝

    深拷贝会另外创造一个一模一样的对象,新旧对象不共享内存,因此修改其中的一个对象不会改到另一个对象。

    深拷贝的几种方式

    1. 手动复制

    obj1 = {a:1,b:2}
    obj2 = {a: obj1.a,b: obj.b}

    2. JSON.parse(JSON.stringify())

    用JSON.stringify转为字符串 再用JSON.parse把字符串再转为新的对象

    可以处理数组和对象的深拷贝,但是不能处理函数和正则,因为这两者基于这两个函数处理后得到的结果不再是正则/函数

    缺点:

    1. 会忽略undefined
    2. 会忽略symbol
    3. 不能序列化函数
    4. 不能解决循环引用的对象

    4. 递归拷贝

    递归深拷贝的实现:

      var deepCopy = function(obj) {
      if (typeof obj !== 'object') return
      var newObj = obj instanceof Array ? [] : {}
      for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
          newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
        }
      }
      return newObj
    }

    缺点: 相互引用会出现死循环,深拷贝的做法是遇到对象就进行递归 复制,那么结果只能无限循环下去

    5. object.create()方法

    Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

    也就是说,现有对象是新的对象的构造函数的prototype.其实现过程如下:

    function create(obj) {
      function F() {}
      F.prototype = obj
      return new F()
    }

    6. 直接使用一些库函数方法, 如lodash

    var _ = require('lodash')
    _.cloneDeep()



  • 相关阅读:
    BAT脚本打印空行的使用方法
    Shell脚本关于屏幕输出的字符进行颜色控制的问题
    shell脚本中切换用户执行相应的命令或者shell脚本的方法
    Linux下执行的java命令重定向到文件中的方法
    解决Firefox浏览器每次打开都弹出导入向导的问题
    解决Ruby在IE11中报Unable to get browser (Selenium::WebDriver::Error::NoSuchWindowError)的错误
    6月28日 Django form组件 和 modelform组件
    6月27日 ajax
    6月25日 Django 分页 cookie、session
    6月26日 Django 中间件
  • 原文地址:https://www.cnblogs.com/SF9924/p/14145502.html
Copyright © 2011-2022 走看看