1. 浅拷贝原理
浅拷贝是拷贝的引用 一般情况下,浅拷贝只会拷贝一层 层级结构特别深的话,如果拷贝的不是最深层数据的值,都为浅拷贝
2. 浅拷贝实现
let obj = {
name: "小红" ,
age: 18 ,
hobby: {
a: "aaa" ,
b: "bbb"
}
}
let newObj = { }
for ( let i in obj) {
newObj[ i] = obj[ i]
}
newObj. name = "小黄"
console. log ( newObj. name) ;
console. log ( obj. name) ;
newObj. hobby. a = "AAA"
console. log ( newObj. hobby. a) ;
console. log ( obj. hobby. a) ;
3. 深拷贝原理
深拷贝是拷贝的值 为基本数据类型的话就自接拷贝,引用数据类型的话就进入深层去拷贝 因为引用数据类型是对基本数据类型的存储方式
4. 深拷贝实现
let obj = {
num: 123 ,
str: 123 ,
bool: true ,
unde: undefined,
nul: null ,
nan: NaN ,
infin: Infinity ,
sym: Symbol ( 1 ) ,
date: new Date ( ) ,
reg: new RegExp ( /asdfsd/ ) ,
fn ( ) {
let i = 10
} ,
arr: [ 1 , 2 , 3 , 4 ] ,
obj: {
a: "111" ,
b: "222"
} ,
set : new Set ( [ 1 , 2 , 3 , 4 ] ) ,
map: new Map ( [
[ "aaa" , "AAA" ] ,
[ "bbb" , "BBB" ]
] )
}
4.1 乞丐版深拷贝
let newObj = JSON . parse ( JSON . stringify ( obj) )
拷贝的对象中的函数、undefined、symbol 这几种类型,序列化之后的字符串中这个键值对会消失 拷贝 Date 引用类型会变成字符串; 无法拷贝不可枚举的属性; 无法拷贝对象的原型链; 拷贝 RegExp、Set、Map引用类型会变成空对象; 对象中含有 NaN、Infinity 以及 -Infinity,JSON 序列化的结果会变成 null; 无法拷贝对象的循环应用(对象内部含有外部的引用) BigInt不能被序列化,会报错
4.2 递归实现深拷贝
function deepCopy ( target) {
let result = Array. isArray ( target) ? [ ] : { }
for ( let i in target) {
if ( typeof target[ i] === "object" && target[ i] !== null ) {
result[ i] = deepCopy ( target[ i] )
} else {
result[ i] = target[ i]
}
}
return result
}
4.3 递归升级版
const isComplexDataType = obj => ( typeof obj === 'object' || typeof obj === 'function' ) && ( obj !== null )
const deepClone = function ( obj, hash = new WeakMap ( ) ) {
if ( obj. constructor === Date)
return new Date ( obj)
if ( obj. constructor === RegExp)
return new RegExp ( obj)
if ( hash. has ( obj) ) return hash. get ( obj)
let allDesc = Object. getOwnPropertyDescriptors ( obj)
let cloneObj = Object. create ( Object. getPrototypeOf ( obj) , allDesc)
hash. set ( obj, cloneObj)
for ( let key of Reflect. ownKeys ( obj) ) {
cloneObj[ key] = ( isComplexDataType ( obj[ key] ) && typeof obj[ key] !== 'function' ) ? deepClone ( obj[ key] , hash) : obj[ key]
}
return cloneObj
}