js 对象的浅拷贝与深拷贝

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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容