栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

理解JavaScript的深浅拷贝

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

理解JavaScript的深浅拷贝

一、深浅拷贝
// 目标数组
var targetArr = [10, 20, 30, [40, 50, 60]]

// 目标对象
var targetObj = {
  name: 'bobo',
  like: {
    eat: {
      fruit: 'Mango'
    },
    coding: 'js',
  },
  getName: function () {
    return this.name
  }
}
二、数组浅拷贝 2.1.第一种方法

使用数组的 concat 方法来实现:

var cloneTarget = [].concat(targetArr)
2.2.第二种方法

使用数组的 slice 方法来实现

var cloneTarget = targetArr.slice()
2.3.第三种方法

通过...展开运算符实现浅拷贝

var cloneTarget = [...targetArr]
三、对象浅拷贝 3.1.第一种方法

Object.assign(target, ...sources) 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。第一个参数是目标对象,第二个参数是一个或多个源对象。

代码实现:

var cloneTarget = Object.assign({}, targetObj)
3.2.第二种方法

通过...展开运算符实现浅拷贝

var cloneTarget = {...targetObj}
3.3.浅拷贝缺点

浅拷贝缺点:如果源对象的属性值是指向一个对象的引用,它也只是拷贝那个引用值。

console.log(cloneTarget.like.coding) // js
targetObj.like.coding = 'css' // 修改源对象的like属性对象
console.log(cloneTarget.like.coding) // css 拷贝的对象也变成了css
四、实现浅拷贝的方法

自己实现一个浅拷贝的方法,这个方法可以理解为前几个方法的原理,实际上就是根据传入的参数类型,创建一个对象或数组,然后将每个属性赋给新的对象或者数组:

function shallowCopy(obj) {
  // 判断是否为对象
  if (typeof obj !== 'object' || obj == null) {
    return obj
  }

  // 判断传入的对象是函数还是对象
  var newObj = obj instanceof Array ? [] : {}
  for (var key in obj) {
    // 只拷贝obj上的的属性
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key]
    }
  }

  return newObj
}
五、深拷贝 5.1.第一种方法

使用 JSON.parse(JSON.stringify(object)) 实现:

var deepClone = JSON.parse(JSON.stringify(targetObj))
var deepClone = JSON.parse(JSON.stringify(targetArr))

缺点:

  1. 会忽略 undefined
  2. 会忽略 symbol
  3. 不能序列化函数
  4. 不能解决循环引用的对象
5.2.自己实现深拷贝方法

在刚才实现的浅拷贝方法上,再判断一下属性值的类型,如果是对象,我们递归调用深拷贝函数即可:

function deepClone(obj) {
  // 判断是否为对象
  if (typeof obj !== 'object' || obj == null) {
    return obj
  }
  var newObj = obj instanceof Array ? [] : {}
  for (var key in obj) {
    // 只拷贝obj上的的属性
    if (obj.hasOwnProperty(key)) {
      // 如果属性值是对象,我们递归调用深拷贝函数
      newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
    }
  }
  return newObj
}
六、总结
类别 和源数据是否指向同一个对象 第一层为基本数据类型 源数据中包含子对象
赋值 改变原数据一同改变 改变原数据一同改变
浅拷贝 改变原数据不会一同改变 改变原数据一同改变
深拷贝 改变原数据不会一同改变 改变原数据不会一同改变
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号