乐趣区

关于javascript:js-深拷贝和浅拷贝

定义

深拷贝:复制对象与原对象互不影响
浅拷贝:复制对象与原对象首层互不影响

常见的深拷贝

  1. JSON.parse(JSON.stringify())
  2. 手动封装 deepCopy

常见的浅拷贝

  1. Object.assign()
  2. es6 扩大运算符
  3. shallowCopy

原理

首先咱们要理解无论深拷贝还是浅拷贝都是对援用数据类型而言,根底数据类型是不存在深浅拷贝的概念的,为什么呢?让咱们先来理解连个存储空间 – 栈和堆

栈:主动调配,存储空间小,个别用来存储确定空间大小的数据,主动开释内存
堆:存储空间大,存储不确定空间大小的数据,须要手动开释内存

下面咱们简略的介绍了栈堆特点,js 的根底数据类型个别都是确定了存储空间的大小,也就是是说每一个根底数据类型都是 独立存在 栈中 互不影响 所以不存在深浅拷贝,而援用数据类型则不是他们存储在堆中,通过调用栈中的援用地址来拜访堆援用数据 ,多个援用地址指向同一块堆中内存,当咱们 批改数据是其实是通过援用地址批改堆中的内存数据,所以牵一发而动全身,有时这种景象是我不不想看到的,所以呈现了深浅拷贝

所以原理很简略,将咱们须要切断分割的数据从新开拓一款内存空间这样咱们就实现了深浅拷贝

深拷贝:所有属性都会开拓一块新的内存空间,来切断与原对象的分割
浅拷贝:只在首层属性开拓新的内存空间,如果原对象多层嵌套其余嵌套层仍然复制援用地址

例子:

// 深拷贝 正反序列 JSON.parse(JSON.stringify())
var obj = {
  name:'zs',
  info:{
    age: 18,
    sex: '男'
  }
}

var obj1 = JSON.parse(JSON.stringify(obj))
obj1.name = 'ls'
obj1.info.age = 22
console.log(obj.name,obj.info.age,obj1.name,obj1.info.age) // zs 18 ls 22
// 浅拷贝 扩大运算符
var obj = {
  name:'zs',
  info:{
    age: 18,
    sex: '男'
  }
}

var obj1 = {...obj}
obj1.name = 'ls'
obj1.info.age = 22
console.log(obj.name,obj.info.age,obj1.name,obj1.info.age)  // zs 22 ls 22
// 浅拷贝 Object.assign
var obj = {
  name:'zs',
  info:{
    age: 18,
    sex: '男'
  }
}

var obj1 = Object.assign({},obj)
obj1.name = 'ls'
obj1.info.age = 22
console.log(obj.name,obj.info.age,obj1.name,obj1.info.age) // zs 22 ls 22

留神:Object.assign 第一个参数不是空对象或空数组它仅仅是复制内存地址

退出移动版