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 第一个参数不是空对象或空数组它仅仅是复制内存地址

你可能感兴趣的:(javascript)