深浅拷贝

浅拷贝和深拷贝只针对引用类型

浅拷贝

浅拷贝:拷贝的是地址

如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响

拷贝对象之后,里面的属性值简单数据类型直接拷贝值

如果属性值是引用数据类型则拷贝的是地址

总结:

如果是简单数据类型拷贝值,引用数据类型拷贝的是地址 (简单理解: 如果是单层对象,没问题,如果有多层就有问题)

常见方法:

  1. 拷贝对象:Object.assgin() / 展开运算符 {...obj} 拷贝对象
  2. 拷贝数组:Array.prototype.concat() 或者 [...arr]

直接赋值和浅拷贝区别:

直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址

浅拷贝:如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响

// 浅拷贝:只拷贝最外面一层
const obj = {
  uname : '小明',
  age : 18,
  gender : 'man',
  color : ['red', 'green', 'yellow'],
  family : {
    mother : 'mama',
    father : 'baba'
  }
}
// const o = {}

// 基本类型,栈中存的是数据,拷贝的也是数据
// 引用数据类型,栈中存的是数据在内存中的地址,拷贝的也是地址

// 方法1:遍历
// 有该属性就修改属性值,没有该属性就添加属性
//// o['uname'] = obj['uname']
// for (const key in obj) {
//   o[key] = obj[key]  
// }

// 方法2:Object静态方法:assign:将后面对象中的成员添加到前面对象(修改/添加)
// Object.assign(o,obj)

// 方法3:扩展运算符
const o = {...obj}


// 如果是简单数据类型拷贝值,引用数据类型拷贝的是地址 
// (简单理解: 如果是单层对象,没问题,如果有多层就有问题)
o.age = 20
o.color[0] = 'pink'
o.family.mother = '妈妈'
console.log(o, obj)

深拷贝

深拷贝:拷贝的是对象,不是地址

常见方法

通过递归实现深拷贝

函数递归:

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数

简单理解:函数内部自己调用自己, 这个函数就是递归函数

递归函数的作用和循环效果类似

由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return

let num = 1

function fn () {

  console.log(`第${num}次打印`)

  if(num >= 6) {
    return
  }

  num++

  fn()
}

fn()

递归实现深拷贝

const obj = {
  uname : '小明',
  age : 18,
  gender : 'man',
  color : ['red', 'green', 'yellow'],
  family : {
    mother : 'mama',
    father : 'baba'
  }
}

const o = {}

// 利用递归
function deepCopy (newObj, oldObj) {

  for (const key in oldObj) {
    //  oldObj[key] : 当前属性对应的属性值
    // 必须先查看数组,因为数组属于对象,对象不一定是数组
    // 查看原型链中是否包含数组  
    if (oldObj[key] instanceof Array){
      // 如果oldObj[key] 是数组,那么newObj[key]也得是数组
      newObj[key] = []
      deepCopy(newObj[key], oldObj[key])
      
    } else if (oldObj[key] instanceof Object){
      // 如果oldObj[key] 是对象,那么newObj[key]也得是对象
      newObj[key] = {}
      deepCopy(newObj[key], oldObj[key])

    }
    else {
      // 如果oldObj[key] 是基本数据类型,直接赋值
      newObj[key] = oldObj[key]
    }
  }
}

deepCopy(o, obj)

o.age = 20
o.color[0] = 'pink'
o.family.mother = '妈妈'
conso

lodash/cloneDeep

利用js库 lodash里面的 _.cloneDeep()

语法:const o = _.cloneDeep(obj)

通过JSON.stringify()实现

利用JSON字符串转换

语法:const o = JSON.parse(JSON.stringify(obj))

<script src="./js/lodash.min.js"></script>
<script>
  const obj = {
    uname : '小明',
    age : 18,
    gender : 'man',
    color : ['red', 'green', 'yellow'],
    family : {
      mother : 'mama',
      father : 'baba'
    }
  }

  // 利用js库 lodash里面的 _.cloneDeep()
  // const o = _.cloneDeep(obj)

  //利用JSON字符串转换
  const o = JSON.parse(JSON.stringify (obj))

  o.age = 20
  o.color[0] = 'pink'
  o.family.mother = '妈妈'
  console.log(o, obj)//o,obj互不影响
</script>
posted @ 2022-05-26 19:08  丫丫learning  阅读(30)  评论(0编辑  收藏  举报