深拷贝和浅拷贝
**在日常开发过程中,咱们常常会波及到数据的拷贝。有时候会有困惑,到底是应用深拷贝还是浅拷贝,
咱们先来明确一下什么是深拷贝什么是浅拷贝**
对于对深拷贝和浅拷贝的定义:
浅拷贝
- 如果属性都是根本数据类型,那么就是拷贝根本数据类型的值
如果属性外面有援用数据类型,那么拷贝的就是内存地址,这时批改新对象,对导致原对象也被批改了
深拷贝
- 如果属性都是根本数据类型,那么就是拷贝根本数据类型的值
- 如果属性外面有援用数据类型( 对象 ),那么会创立新的对象,将原对象的属性和值拷贝进去,放到新对象外面,并且批改新对象不会对原对象产生影响
浅拷贝的实现计划
ES6的开展运算符
/* 应用ES6的开展运算符 */ const arr = [1,2,3,4] const obj = {name:"张三",age:12} const newArr = [...arr] const newObj = {...obj} console.log(newArr) // [1, 2, 3, 4] console.log(newObj) // {name: '张三', age: 12}
Object.assign(指标对象,拷贝源)
/* Object.assign(target,sources) 第一个参数:指标对象 ( 拷贝到的对象 ) 第二个参数:拷贝源 ( 要被拷贝的原对象 ) */ const obj = { name: '张三', age: 10 } const arr = [1, 2, 3] const newObj = Object.assign({}, obj) const newArr = Object.assign([], arr) console.log(newObj) // {name: '张三', age: 10} console.log(newArr) // [1, 2, 3]
应用浅拷贝来拷贝对象外面还有对象的数据时产生的影响
/* 如果对象外面有援用数据类型( 就是对象外面蕴含了对象 ),应用浅拷贝, 那么批改了拷贝进去的对象,会导致原对象也被批改了 */ const obj = { name: '张三', age: 10, info: { address: '湖北', postcode: '430000', }, } const newObj = { ...obj } // 如果批改了对象外面的援用数据类型的数据,会导致原对象也被批改 newObj.info.postcode = '410000' console.log(newObj.info) // {address: '湖北', postcode: '410000' console.log(obj.info) // {address: '湖北', postcode: '410000'}
深拷贝的实现计划
JSON.parse(JSON.stringify(sources))
/* 如果对象外面有援用数据类型( 就是对象外面蕴含了对象 ),应用深拷贝, 那么批改了拷贝进去的对象,不会导致原对象也被批改了 */ const obj = { name: '张三', age: 10, info: { address: '湖北', postcode: '430000', }, } const newObj = JSON.parse(JSON.stringify(obj)) newObj.info.postcode = '410000' console.log(newObj.info) // {address: '湖北', postcode: '410000'} console.log(obj.info) // {address: '湖北', postcode: '430000'}
应用递归拷贝
// object:要被拷贝的对象 hash默认创立一个空map function deepCopy(object, hash = new Map()) => { // 判断是否是援用数据类型,如果不是间接返回 if (typeof object != 'object') return object // 判断 hash外面是否有这个key,如果有也返回 if (hash.get(object)) { return object } // 能执行到这里的只有数组和对象 // object.constructor指向构造函数自身,通过构造函数创建对象或者数组 let container = new object.constructor() // 向map中存这个key,当前循环的时候如果这个key存在,那么就不在持续循环 hash.set(object, container) for (let key in object) { // 如果 object是对象那么,这里的key示意对象的键 // 如果是object是数组,那么key示意数组元素的下标 // 而后这边递归调用,直到object外面没有援用数据类型,那么递归完结 container[key] = deepCopy(object[key], hash) } // 最初返回 这个对象或者数组 return container } const obj = { name: '张三', info: { age: 10, }, } const newObj = deepCopy(obj) newObj.info.age = 20 console.log(newObj.info) // {address: '湖北', postcode: '410000' console.log(obj.info) // {address: '湖北', postcode: '410000'}
本文内容次要包含:
- 浅拷贝和深拷贝的区别
实现浅拷贝的两种形式
- es6的开展运算符
- Object.assign()
实现深拷贝的两种形式
- 1: JSON.parse(JSON.stringify)实现深拷贝
- 2: 应用递归函数进行深拷贝