写点什么

浅拷贝、深拷贝

作者:源字节1号
  • 2022 年 6 月 01 日
  • 本文字数:1314 字

    阅读完需:约 4 分钟

浅拷贝、深拷贝

由于JavaScript中对象是引用类型,保存的是地址,深、浅拷贝的区别是,当拷贝结束后,在一定程度上改变原对象中的某一个引用类型属性的值,新拷贝出来的对象依然受影响的话,就是浅拷贝,反之就是深拷贝。

浅拷贝的几种实现方法

第一种方法: Object.assign()会拷贝原始对象中的所有属性到一个新对象上,如果属性为对象,则拷贝的是对象的地址,改变对象中的属性值,新拷贝出来的对象依然会受影响。

var obj = {  name: '张三',  age: 23,  isStudent: false,  job: {    name: 'FE',    money: 12  }}var newObj = Object.assign({}, obj);obj.job.money = 21;console.log(newObj.name);     // 输出张三console.log(newObj.age);      // 输出23console.log(newObj.job.money);// 输出21,受影响
复制代码

第二种方法:...扩展运算符是ES6新增加的内容

var obj = {  name: '张三',  age: 23,  isStudent: false}var newObj = {...obj};console.log(newObj.name);     // 输出张三console.log(newObj.age);      // 输出23
复制代码

深拷贝几种实现方式

第一种方法: 利用JSON的序列化和反序列化方法,可以实现简易对象深拷贝,但此种方法有较大的限制:

  1. 会忽略属性值为undefined的属性

  2. 会忽略属性为Symbol的属性

  3. 不会序列化函数

  4. 不能解决循环引用的问题,直接报错

var obj = {  name: '张三',  age: 23,  address: undefined,  sayHello: function() {    console.log('Hello');  },  isStudent: false,  job: {    name: 'FE',    money: 12  }}var newObj = JSON.parse(JSON.stringify(obj));obj.job.money = 21;console.log(newObj.name);      // 输出张三console.log(newObj.age);       // 输出23console.log(newObj.job.money); // 输出12
console.log(newObj.address); // 报错console.log(newObj.sayHello());// 报错
复制代码

第二种: 实现自己简易的深拷贝函数

function deepClone(obj) {  function isObject(o) {    return (typeof o === 'object' || typeof o === 'function') && o !== null;  }  if(!isObject(obj)) {    throw new Error('非对象');  }  var isArray = Array.isArray(obj);  var newObj = isArray ? [...obj] : {...obj};  Reflect.ownKeys(newObj).forEach(key => {    newObj[key] = isObject(newObj[key]) ? deepClone(newObj[key]) : newObj[key];  })  return newObj;}var obj = {  name: 'AAA',  age: 23,  job: {    name: 'FE',    money: 12000  }}var cloneObj = deepClone(obj);obj.job.money = 13000;console.log(obj.job.money);     // 输出13000console.log(cloneObj.job.money);// 输出12000
复制代码

第三种方法: 使用lodash第三方函数库实现(需要先引入 lodash.js)

var obj = {  name: '张三',  age: 23,  isStudent: false,  job: {    name: 'FE',    money: 12  }}var newObj = _.cloneDeep(obj);obj.job.money = 21;console.log(newObj.name);     // 输出张三console.log(newObj.age);      // 输出23console.log(newObj.job.money);// 输出12,不受影响
复制代码

如若转载,请注明出处:开源字节   https://sourcebyte.cn/article/145.html

用户头像

源字节1号

关注

一个着迷于技术又喜欢不断折腾的技术活跃者 2022.03.09 加入

一个着迷于技术又喜欢不断折腾的技术活跃者。喜欢并热爱编程,执着于努力之后所带来的美好生活!

评论

发布
暂无评论
浅拷贝、深拷贝_软件开发_源字节1号_InfoQ写作社区