美文网首页
js 对象拷贝 浅拷贝 深拷贝

js 对象拷贝 浅拷贝 深拷贝

作者: ynwshy | 来源:发表于2021-02-23 14:31 被阅读0次

浅拷贝

Object.assign(target, source)

var obj1 = {
    a: 1,
    b: 2,
    c: ['a','b','c']
}
var obj2 = Object.assign({}, obj1);
obj2.c[1] = 5;
console.log(obj1.c); // ["a", 5, "c"]
console.log(obj2.c); // ["a", 5, "c"]

扩展运算符(...)

const a = {msg: {name: "lihb"}};
const b = {...a};
a.msg.name = "lily";
console.log(b.msg.name); // lily

深拷贝

乞丐版的深拷贝 JSON.stringify(JSON.parse(obj))

 var obj1 = {
    a: 1,
    b: 2,
    c: 3
}
var objString = JSON.stringify(obj1);
var obj2 = JSON.parse(objString);
obj2.a = 5;
console.log(obj1.a);  // 1
console.log(obj2.a); // 5

递归拷贝

null、undefinde、function、RegExp等特殊的值也全部拷贝成功

function deepClone(source) {
    if (typeof source !== "object") { // 非对象类型(undefined、boolean、number、string、symbol),直接返回原值即可
        return source;
    }
    if (source === null) { // 为null类型的时候
        return source;
    }
    if (source instanceof Date) { // Date类型
        return new Date(source);
    }
    if (source instanceof RegExp) { // RegExp正则类型
        return new RegExp(source);
    }
    let result;
    if (Array.isArray(source)) { // 数组
        result = [];
        source.forEach((item) => {
            result.push(deepClone(item));
        });
        return result;
    } else { // 为对象的时候
        result = {};
        const keys = [...Object.getOwnPropertyNames(source), ...Object.getOwnPropertySymbols(source)]; // 取出对象的key以及symbol类型的key
        keys.forEach(key => {
            let item = source[key];
            result[key] = deepClone(item);
        });
        return result;
    }
}
let a = {name: "a", msg: {name: "lihb"}, date: new Date("2020-09-17"), reg: new RegExp(/123/)};
let b = deepClone(a);
a.msg.name = "lily";
a.date = new Date("2020-08-08");
a.reg = new RegExp(/456/);
console.log(b);
// { name: 'a', msg: { name: 'lihb' }, date: 2020-09-17T00:00:00.000Z, reg: /123/ }

利用WeakMap、递归实现对象深拷贝。解决拷贝对象环引用爆栈问题

解决对象相互引问题

function checktype(obj){ //检查对象类型
    return Object.prototype.toString.call(obj).slice(8,-1)
}
function depCopy(target,hash = new WeakMap()){ //hash 作为一个检查器,避免对象深拷贝中出现环引用,导致爆栈。
    let type = checktype(target)
    let result = null
    if(type=="Object"){
        result = {}
    }else if(type=="Array"){
         result = []
    }else{
        return target
    }
    if(hash.has(target)){ //检查是有存在相同的对象在之前拷贝过,有则返回之前拷贝后存于hash中的对象
        return hash.get(target)
    }
    hash.set(target,result) //备份存在hash中,result目前是空对象、数组。后面会对属性进行追加,这里存的值是对象的栈
    for(let i in target){
        if(checktype(target[i])=="Object"||checktype(target[i])=="Array"){
             result[i]= depCopy(target[i],hash)//属性值是对象,进行递归深拷贝
        }else{
             result[i]= target[i]//其他类型直接拷贝
        }
       
    }
    return result

}

var b={gg:123,ff:a}
var a={
    c:{
        k:1,
        k2:2
    },
    d:{
        d1:[1,2],
        d2:b,
        d3:{
            f1:'kkk'
        }
    }
}

let cop = depCopy(a)

参考 https://segmentfault.com/a/1190000024498621

相关文章

  • JS实现深拷贝、instanceof、判断是否为数组

    JS深拷贝 JS中拷贝对象可以按照拷贝的程度可以分为浅拷贝和深拷贝,有些时候我们需要拷贝之后的对象和拷贝之前的对象...

  • JS中对象的复制

    JS中的对象复制分为两种情况:深拷贝和浅拷贝。深拷贝和浅拷贝的区别在于对数组和对象的拷贝,对它们拷贝时浅拷贝只是拷...

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • java 对象的拷贝

    拷贝:即复制 对象拷贝:即对象复制 java 对象拷贝分类:浅拷贝、深拷贝 java 对象的浅拷贝和深拷贝针对包含...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

  • 2018-10-10day9函数基础

    1.浅拷贝、深拷贝 copy.copy(对象):浅拷贝copy.deepcopy(对象):深拷贝""" """拷贝...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • 深拷贝浅拷贝

    1.拷贝可变对象 深拷贝后浅拷贝可变对象,都是内存复制。 输出结果: 2.拷贝不可变对象 浅拷贝是指针拷贝,深拷贝...

  • 深拷贝和浅拷贝不同

    浅拷贝:指针(地址)拷贝,不会产生新对象深拷贝:内容拷贝,会产生新对象 非容器类对象的深拷贝、浅拷贝 非容器类对象...

网友评论

      本文标题:js 对象拷贝 浅拷贝 深拷贝

      本文链接:https://www.haomeiwen.com/subject/ndvrfltx.html