美文网首页
js 对象的浅拷贝与深拷贝

js 对象的浅拷贝与深拷贝

作者: 弹力盒 | 来源:发表于2021-08-10 10:19 被阅读0次

1、对象的浅拷贝及方法

  • a、定义

拷贝的是源对象的指针,修改其中一个对象,原对象和拷贝对象都会受到影响

  • b、Object.assign(object) 方法
/**
 * 构造函数,用于生成对象实例
 */
function ORIGINOBJ () {
  const obj = {
    A: 'AAAAAAA',
    B: 'BBBBBBB',
    C: function () {
      console.log('yeah!!!')
    },
    D: ['DD1', 'DD2', 'DD3'],
    E: {
      EA: ['EA1', 'EA2', 'EA3'],
      EB: {
        EBA: () => {
          console.log('Wa hahaha!!!!')
        },
        EBB: null,
        EBC: undefined
      }
    },
    F: null,
    G: undefined,
    H: false
  }
  // 遍历生成构造函数 this 对象上的方法、属性,用于生成实例对象
  for (let i in obj) {
    this[i] = obj[i]
  }
}

// 在原对象实例上添加方法、属性
ORIGINOBJ.prototype.speak = function () {
  console.log('wa Haaaaa!!!')
}
ORIGINOBJ.prototype.name = 'ORIGINOBJ'
ORIGINOBJ.prototype.type = undefined

// new 一个对象
const originObject = new ORIGINOBJ()

/**
 * Object.assign 复制对象时,值得注意的是
 * 第一层的数据是深拷贝
 * 第二层以后面层次的则是浅拷贝
 */
const assignObject = Object.assign({}, originObject)
assignObject.A = 'hahah' // 原对象的数据没改变
assignObject.E.EB = 'hahah' // 原对象的数据改变了
console.log(originObject)
console.log(assignObject)

打印结果如下


image.png

二、对象的深拷贝及方法

将原对象拷贝到另一个内存中,修改其中一个对象,另一个对象并不会收到影响,具体方法如下

  • a、利用 JSON.parse(JSON.stringify(originObject)) 的方法深拷贝
/**
 * 构造函数,用于生成对象实例
 */
function ORIGINOBJ () {
  const obj = {
    A: 'AAAAAAA',
    B: 'BBBBBBB',
    C: function () {
      console.log('yeah!!!')
    },
    D: ['DD1', 'DD2', 'DD3'],
    E: {
      EA: ['EA1', 'EA2', 'EA3'],
      EB: {
        EBA: () => {
          console.log('Wa hahaha!!!!')
        },
        EBB: null,
        EBC: undefined
      }
    },
    F: null,
    G: undefined,
    H: false
  }
  // 遍历生成构造函数 this 对象上的方法、属性,用于生成实例对象
  for (let i in obj) {
    this[i] = obj[i]
  }
}

// 在原对象实例上添加方法、属性
ORIGINOBJ.prototype.speak = function () {
  console.log('wa Haaaaa!!!')
}
ORIGINOBJ.prototype.name = 'ORIGINOBJ'
ORIGINOBJ.prototype.type = undefined

// new 一个对象
const originObject = new ORIGINOBJ()

/**
 * JSON.parse(JSON.stringify()) 深拷贝
 * 一、弊端
 * 1、对于值为 undefined 的属性不能复制过来
      (虽然不影响,因为不存在时即为 undefined)
 * 2、对于值为函数的属性不能复制过来
 * 3、不能复制原对象原型上的方法和属性
*/
const jsonObject = JSON.parse(JSON.stringify(originObject))
// 修改深拷贝的对象,原对象的值并不会改变
jsonObject.A = 'hahah'
console.log(originObject)
console.log(jsonObject)
console.log(jsonObject.name) // undefined
console.log(jsonObject.type) // undefined
jsonObject.speak() // 报错 jsonObject.speak is not a function

打印结果如下


image.png
  • b、利用 lodash 插件 的 cloneDeep 方法深拷贝
import _ from 'lodash'
const { cloneDeep } = _

/**
 * 构造函数,用于生成对象实例
 */
function ORIGINOBJ () {
  const obj = {
    A: 'AAAAAAA',
    B: 'BBBBBBB',
    C: function () {
      console.log('yeah!!!')
    },
    D: ['DD1', 'DD2', 'DD3'],
    E: {
      EA: ['EA1', 'EA2', 'EA3'],
      EB: {
        EBA: () => {
          console.log('Wa hahaha!!!!')
        },
        EBB: null,
        EBC: undefined
      }
    },
    F: null,
    G: undefined,
    H: false
  }
  // 遍历生成构造函数 this 对象上的方法、属性,用于生成实例对象
  for (let i in obj) {
    this[i] = obj[i]
  }
}

// 在原对象实例上添加方法、属性
ORIGINOBJ.prototype.speak = function () {
  console.log('wa Haaaaa!!!')
}
ORIGINOBJ.prototype.name = 'ORIGINOBJ'
ORIGINOBJ.prototype.type = undefined

// new 一个对象
const originObject = new ORIGINOBJ()

/**
 * lodash cloneDeep 方法深拷贝
 * 一、优点
 * 1、不存在JSON.parse(JSON.stringify()) 方法的弊端
 * 2、能够完美的深拷贝原来的对象,包括原对象上的原型方法和属性
 * 
 * 二、弊端
 * 1、需要引入 lodash 这个额外的依赖
*/
const cloneDeepObject = cloneDeep(originObject)
// 修改深拷贝的对象,原对象的值并不会改变
cloneDeepObject.A = 'hahah'
console.log(originObject)
console.log(cloneDeepObject)
console.log(cloneDeepObject.name) // ORIGINOBJ
console.log(cloneDeepObject.type) // undefined
cloneDeepObject.speak() // wa Haaaaa!!!

打印结果如下:


image.png
  • c、利用自定义的 cloneDeep 方法深拷贝
/**
 * 构造函数,用于生成对象实例
 */
function ORIGINOBJ () {
  const obj = {
    A: 'AAAAAAA',
    B: 'BBBBBBB',
    C: function () {
      console.log('yeah!!!')
    },
    D: ['DD1', 'DD2', 'DD3'],
    E: {
      EA: ['EA1', 'EA2', 'EA3'],
      EB: {
        EBA: () => {
          console.log('Wa hahaha!!!!')
        },
        EBB: null,
        EBC: undefined
      }
    },
    F: null,
    G: undefined,
    H: false
  }
  // 遍历生成构造函数 this 对象上的方法、属性,用于生成实例对象
  for (let i in obj) {
    this[i] = obj[i]
  }
}

// 在原对象实例上添加方法、属性
ORIGINOBJ.prototype.speak = function () {
  console.log('wa Haaaaa!!!')
}
ORIGINOBJ.prototype.name = 'ORIGINOBJ'
ORIGINOBJ.prototype.type = undefined

// new 一个对象
const originObject = new ORIGINOBJ()

/**
 * 自定义封装的 deepCopy 方法来深拷贝对象
 * 一、优点
 * 1、不存在JSON.parse(JSON.stringify()) 方法的弊端
 * 2、原型上面的属性、方法将被添加到拷贝对象的实例上
 * 3、能够完美的深拷贝原来的对象
 */

function deepCopy (source) {
  let target = Array.isArray(source) ? [] : {}
  for (let i in source) {
    if (typeof source[i] === 'object') {
      target[i] = deepCopy(source[i])
    } else {
      target[i] = source[i]
    }
  }
  return target
}

const deepCopeObject = deepCopy(originObject)
// 修改深拷贝的对象,原对象的值并不会改变
deepCopeObject.A = 'hahah'
console.log(originObject)
console.log(deepCopeObject)

打印结果如下:


image.png

相关文章

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • JS实现深拷贝、instanceof、判断是否为数组

    JS深拷贝 JS中拷贝对象可以按照拷贝的程度可以分为浅拷贝和深拷贝,有些时候我们需要拷贝之后的对象和拷贝之前的对象...

  • JS中对象的复制

    JS中的对象复制分为两种情况:深拷贝和浅拷贝。深拷贝和浅拷贝的区别在于对数组和对象的拷贝,对它们拷贝时浅拷贝只是拷...

  • 深浅拷贝,面向对象,Symbol,Set,Map

    一:浅拷贝与深拷贝对象的浅拷贝:浅拷贝是对象共用的一个内存地址,对象的变化相互影响。对象的深拷贝:简单理解深拷贝是...

  • 前端笔记(二) 对象的深浅拷贝,函数的防抖与节流,函数柯里化 ,

    对象的深浅拷贝 对象的深拷贝与浅拷贝的区别: 浅拷贝:仅仅复制对象的引用, 而不是对象本身。 深拷贝:把复制的对象...

  • JAVA设计模式:原型模式与拷贝

    深拷贝与浅拷贝 浅拷贝:对象A进行赋值操作得到对象B,这就是浅拷贝,修改对象A的属性会影响到B的属性 深拷贝:深拷...

  • iOS - copy与mutableCopy

    浅拷贝与深拷贝 浅拷贝:指针拷贝,不产生新的对象,源对象的引用计数器+1 深拷贝:对象拷贝,会产生新的对象,源对象...

  • js中的深拷贝和浅拷贝

    一、深拷贝与浅拷贝 深拷贝和浅拷贝只针对Object,Array这些复杂的引用对象。浅拷贝,只复制对象的引用的地址...

  • C++封装(二)

    第2章 对象成员与对象数组 第3章 深拷贝与浅拷贝 浅拷贝: 深拷贝: 第4章 对象指针 对象指针: 栈中: 对象...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

网友评论

      本文标题:js 对象的浅拷贝与深拷贝

      本文链接:https://www.haomeiwen.com/subject/xshypltx.html