浅拷贝
```对象复制
Object.assign()
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2); // 返回 {a:1, b:2, c:3}
target // {a:1, b:2, c:3}
深拷贝
JSON,parse(JSON.stringify)
var obj = {
a: 2,
b: [1,2,3,{aa: 11, bb:22}],
c: function () {
console.log("cccc")
},
d: undefined,
e: 'e',
f: /^\d+$/
}
// let obj1 = JSON.parse(JSON.stringify(obj)) // 会丢失c的function 和d的undefined 正则({})/日期格式 会改变
// 方法1
function deepClone (obj) {
let objClone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) { // 如果是私有属性 不是原型上的才进入
if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
deepClone(obj[key])
} else {
objClone[key] = obj[key]
}
}
}
return objClone
}
let obj2 = deepClone(obj)
console.log(obj2)
// 方法2
function deepClone2 (obj) {
//过滤特殊情况
if (obj === null) return;
if (typeof obj != 'object') return obj;
if (obj instanceof RegExp) {
return new RegExp(obj)
}
// => 不直接创建空对象的目的,克隆的结果和之前保持相同的所属类
let newObj = new obj.constructor;
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone2(obj[key])
}
}
return newObj;
}
let obj3 = deepClone2(obj);
console.log(obj3)
```javascript
1. js里所有的深拷贝都是最外层的深拷贝,内存还是浅拷贝,
2. 比如:object.assign, ..., slice, concat
// 2. JSON.stringify和JSON.parse会忽略函数,
时间对象,正则等js内置对象
// 3. 深拷贝的原理是依赖递归逐层拷贝
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]'
|| Object.prototype.toString.call(obj) === '[object Array]'
}
function deepCopy(source,hash = new WeakMap()){
// 判断如果参数不是一个对象,返回改参数
if(!isObject(source)) return source;
if(hash.has(source)) return hash.get(source);
// 如何拷贝过该对象,则直接返回该对象
// 判断参数是对象还是数组来初始化返回值
let res = Array.isArray(source)?[]:{};
hash.set(source,res); // 哈希表添加新对象
// 循环参数对象的key
for(let key in source){
// 如果该key属于参数对象本身
if(Object.prototype.hasOwnProperty.call(source,key)){
// 如果该key的value值是对象,递归调用深拷贝方法进行拷贝
if(isObject(source[key])){
res[key] = deepCopy(source[key],hash);
}else{
// 如果该key的value值不是对象,则把参数对象key的value值赋给返回值的key
res[key] = source[key];
}
}
}
// 返回返回值
return res;
};
// 测试
let obj1 = {
name:'obj.name',
un:undefined,
nu:null,
arr: [1,2,3],
sy:Symbol(123),
say:function(){
console.log(this.name);
},
reg:/\d{6}/g,
date:new Date(),
child:{
name:'child.name'
}
}
obj1.child.child= obj1.child;
let obj2 = deepCopy(obj1);
console.log(obj1);
console.log(obj2);
console.log(obj2.sy === obj1.sy)
console.log(obj2.arr === obj1.arr)
obj2.name = 'obj2.name';
obj2.say();
js深拷贝和浅拷贝怎么实现深拷贝
最新推荐文章于 2024-04-04 09:50:11 发布