let {log} = console;
let originObj = {x: {x1: 1, y1: 2}, y: 3};
Object.defineProperty(originObj,"innumberable",{
enumerable:false,
value:"innumberable"
})
function copyObj(obj,targetObj={}){
return Object.assign(targetObj,obj)
}
console.log(copyObj(originObj))
function copyObj2(obj){
return {...obj}
}
log(copyObj2(originObj))
let originArr = [{x:1},2,3]
function copyArr(arr){
return arr.slice(0)
}
let copya = copyArr(originArr);
originArr[0].x = 22;
originArr[1] = 99;
log(copya)
function copyArr2(arr){
return arr.concat();
}
let copya1 = copyArr2(originArr)
originArr[0].x = 999;
originArr[1] = 0;
log(copya1)
function shallowClone(target){
if(typeof target === "object" && typeof target !== null){
let cloneTarget = Array.isArray(target)?[]:{};
for(let prop in target){
if(target.hasOwnProperty(prop)){
cloneTarget[prop] = target[prop]
}
}
return cloneTarget;
}else{
return target
}
}
log(shallowClone(originObj))
function deepClone(target){
return JSON.parse(JSON.stringify(target));
}
let dp1 = deepClone(originObj);
originObj.x.x1 = 99;
originObj.y = 999
log(dp1)
let dp2 = deepClone(originArr);
originArr[0].x = 33;
originArr[1] = 88;
log(dp2)
/**
* JSON.parse(JSON.stringify()) 的缺点
* 1. 如果键值对的值是函数、undefined或者symbol,那么经过stringify序列化就会消失
* 2. Date()引用对象的值会变成字符串
* 3. RegExp正则,值会变为空对象 {}
* 4. 如果键值对值是NaN、Infinity、-Infinity,经过序列化会变成null
* 5. 不能拷贝对象的原型链
* 6. 不能拷贝对象的循环引用 obj[a] = obj
* 7. 不能拷贝不可枚举值
*/
const wm1 = new WeakMap(),
wm2 = new WeakMap(),
wm3 = new WeakMap();
const o1 = {},
o2 = function() {},
o3 = window;
wm1.set(o1, 37);
wm1.set(o2, 'azerty');
wm2.set(o1, o2); // value 可以是任意值,包括一个对象或一个函数
log(wm1)
log(wm2)
const isComplexDataType = obj=>(typeof obj ==="object" || typeof obj === "function") && (obj !==null);
function deepClone1(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)
}
// getOwnPropertyDescriptors 获取的是对象的所有描述,大对象
let allDesc = Object.getOwnPropertyDescriptors(obj);
log(allDesc,'----allDesc')
let cloneObj = Object.create(Object.getPrototypeOf(obj),allDesc);
hash.set(obj,cloneObj);
log(hash,"---hash")
log(Reflect.ownKeys(obj))
for(let key of Reflect.ownKeys(obj)){
cloneObj[key] = (isComplexDataType(obj[key]) && typeof obj[key] !== "function")?deepClone1(obj[key],hash):obj[key];
}
return cloneObj;
}
let obj = {
num: 0,
str: '',
boolean: true,
unf: undefined,
nul: null,
obj: { name: '我是一个对象', id: 1 },
arr: [0, 1, 2],
func: function () { console.log('我是一个函数') },
date: new Date(0),
reg: new RegExp('/我是一个正则/ig'),
[Symbol('1')]: 1,
};
let dp3 = deepClone1(obj);
log(dp3)
console