zoukankan      html  css  js  c++  java
  • javascript中对象的深复制的几种方法

    javascript中复制一个对象有深复制和浅复制两种方式,二者的区别的浅复制只会复制对象的第一层属性,如果对象的层级比较深且为对象或数组时,那么原对象和目标对象的深层对象或数组会指向内存中同一个对象的实例,修改其中一个也会导致另一个改变。

    深复制则是会复制对象的所有层级的所有属性,在堆内存中重新分配内存,将目标对象指向新的内存空间,这样源对象和目标对象之间没有任何关联,修改其中一个也不会导致另一个被修改。

    浅复制的方式

    1、遍历对象

    function clone(obj) {
      if (obj == null || typeof obj !== 'object') return obj
      var newObj = Array.isArray(obj) ? [] : {}
      for (let i in obj) {
        if (obj.hasOwnProperty(i)) {
          newObj[i] =obj[i]
        }
      }
      return newObj
    }

    2、Object.assign

    var obj2 = Object.assign({}, obj)
    

     Object.assign是ES6新增的一个浅复制对象的方法,https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

    深复制的方式

    1、jQuery的$.extend方法

    $.extend(true, {}, obj)

    jQuery的extend方法可以浅复制对象,根据文档,在extend的第一个参数传入true可以实现深复制 http://api.jquery.com/jQuery.extend/

    2、lodash的_.cloneDeep方法

    var objects = [{ 'a': 1 }, { 'b': 2 }];
     
    var deep = _.cloneDeep(objects);
    console.log(deep[0] === objects[0]); //false

    3、JSON对象的方法

    var obj2 = JSON.parse(JSON.stringify(obj1))

    熟悉js的人对这两个方法肯定不陌生,利用原生JSON对象的两个可以非常方便地实现对象的深复制。

    这种方法也有弊端:

    1. 只能复制能用json表示的属性,比如String、Number、Array等,对于不能用json表示的属性例如Function、Regexp等则会丢失
    2. 对象的原型链丢失
    3. 复制效率较低

    虽说有以上缺点,但是这种方式也足以应对大部分情况了。

    4、递归复制

    function cloneDeep(obj) {
      if (obj == null || typeof obj !== 'object') return obj
      var newObj = Array.isArray(obj) ? [] : {}
      for (let i in obj) {
        if (obj.hasOwnProperty(i)) {
          var value = obj[i]
          newObj[i] = typeof value === 'object' ? clone(value) : value
        }
      }
      return newObj
    }

    这种方式与上面浅复制的遍历对象方式相比只是多了递归调用,即判断对象的属性是否也为对象,是则递归调用遍历这个对象,直到不为对象为止。
    但是这种方式也没有考虑Function、Regexp、Error等类型,需要更多的判断,但是核心思想也还是递归遍历对象复制,另外这种方式比JSON的深复制效率稍高。

  • 相关阅读:
    tensorflow中的name_scope, variable_scope
    tf.data.Dataset类的用法
    tensorflow错误:Shape (10, ?) must have rank at least 3
    最大似然估计、最大后验估计、贝叶斯估计的对比
    自然语言处理简述
    深度学习之GRU网络
    深度学习之Batch Normalization
    自然语言处理之序列标注问题
    Ubuntu安装jdk
    TypeScript 高级类型
  • 原文地址:https://www.cnblogs.com/tgxh/p/7488270.html
Copyright © 2011-2022 走看看