浅拷贝与深拷贝三种方式

浅拷贝

浅拷贝:拷贝的是地址

示例

const o1 = {
  name: 'zs',
  age: 'ls'
}
let o2 = [{
  sex: '男'
}]

  1.拷贝对象:Object.assgin(拷贝后的对象,要被拷入的对象) / 展开运算符 {...obj} 拷贝对象

// 1.Object.assign()
Object.assign(o2, o1)

console.log(o1);   // { name: 'zs', age: 'ls' }
console.log(o2);   // { sex: '男', name: 'zs', age: 'ls' }

// 2.(...)
o2 = { ...o2, ...o1 }

console.log(o1);   // { name: 'zs', age: 'ls' }
console.log(o2);   // { sex: '男', name: 'zs', age: 'ls' }

// 3.for..in..循环
for (const key in o1) {
  o2[key] = o1[key]
}

console.log(o1);   // { name: 'zs', age: 'ls' }
console.log(o2);   // { sex: '男', name: 'zs', age: 'ls' }

直接赋值和浅拷贝有什么区别?

        直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址 ​ 浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响

浅拷贝怎么理解?

        拷贝对象之后,里面的属性值是简单数据类型直接拷贝值 ​ 如果属性值是引用数据类型则拷贝的是地址

深拷贝

1.原生语法写递归

        什么是递归?写递归需要注意什么?

                简单理解:函数自己调用自己,要注意:一定要有结束条件, 配合return, 否则造成栈溢出

 // 递归
let num = 1
// fn就是递归函数
function fn() {
  console.log('我要打印六次');
  if (num >= 6) return
  num++  fn()  // 函数内部自己调用自己 
}
fn()

// 输出为:
我要打印六次
我要打印六次
我要打印六次
我要打印六次
我要打印六次
我要打印六次

①写一个递归函数, 里面用for in循环

②判断是不是数组, 如果是数组, 调用递归函数, 一定要先判断是否为数组, 因为数组也是对象

③判断是不是对象, 如果是对象, 调用递归函数

④开始浅拷贝

// 深拷贝1
const obj = {
  name: 'zs',
  family: {
    father: 'zs',
    mother: 'ls'
  },
  hobby: ['打游戏', '喝奶茶', '熬夜']
}
const target = {}
// 深拷贝三种写法
function deepClone(newObj, oldObj) {
  for (const key in oldObj) {
    if (oldObj[key] instanceof Array) {
      // 判断是否为数组
      newObj[key] = []
      deepClone(newObj[key], oldObj[key])
    } else if (oldObj[key] instanceof Object) {
      // 判断是否为对象
      newObj[key] = {}
      deepClone(newObj[key], oldObj[key])
    } else {
      newObj[key] = oldObj[key]
    }
  }
}
deepClone(target, obj)
// 检验是否深拷贝成功
obj.family.father = '王五'
obj.hobby[0] = '睡觉'
console.log(obj);
console.log(target);

instanceof运算符

        实例对象是否在构造函数的原型链上

[1,2,3] instanceof Array   ----> true
{name: 'zs'} instanceof Array   ----> false
[1,2,3] instanceof Object   ----> true


                        万物皆对象

2.序列化和反序列化

        序列化

                把数据对象 转换为 字符串的过程,叫做序列化,例如:调用 JSON.stringify() 函数的操作,叫做 JSON 序列化

        反序列化

                把字符串 转换为 数据对象的过程,叫做反序列化,例如:调用 JSON.parse() 函数的操作,叫做 JSON 反序列化

                JSON.parse(JSON.stringify(要拷贝的数据)) ----> 返回 深拷贝后的数据

                把取出的字符串数据转换为对象(把复杂数据类型转换为字符串(要拷贝的数据))---->返回拷贝后的数据

// 深拷贝2
const obj = {
  name: 'zs',
  family: {
    father: 'zs',
    mother: 'ls'
  },
  hobby: ['打游戏', '喝奶茶', '熬夜']
}

const newObj = JSON.parse(JSON.stringify(obj))

// 检验是否深拷贝成功
obj.family.father = '王五'
obj.hobby[0] = '睡觉'
console.log(obj);
console.log(newObj);

3.lodash插件

        ①引入lodash.js文件

        ②调用方法 _.cloneDeep(要拷贝的数据) ----> 返回 深拷贝后的数据

// 深拷贝3
const _ = require('lodash')

const obj = {
  name: 'zs',
  family: {
    father: 'zs',
    mother: 'ls'
  },
  hobby: ['打游戏', '喝奶茶', '熬夜']
}

const newObj = _.cloneDeep(obj)

// 检验是否深拷贝成功
obj.family.father = '王五'
obj.hobby[0] = '睡觉'
console.log(obj);
console.log(newObj);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值