千家信息网

JS怎么实现深拷贝和浅拷贝

发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,这篇文章主要介绍"JS怎么实现深拷贝和浅拷贝",在日常操作中,相信很多人在JS怎么实现深拷贝和浅拷贝问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"JS怎么实现深拷贝和浅
千家信息网最后更新 2025年01月17日JS怎么实现深拷贝和浅拷贝

这篇文章主要介绍"JS怎么实现深拷贝和浅拷贝",在日常操作中,相信很多人在JS怎么实现深拷贝和浅拷贝问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"JS怎么实现深拷贝和浅拷贝"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

说道数据拷贝就离不开数据类型,在JS中数据类型分为基本类型和引用类型 基本类型:

number, boolean,string,symbol,bigint,undefined,null

引用类型:

object 以及一些标准内置对象 Array、RegExp、String、Map、Set..

一. 基本类型数据拷贝

基本类型数据都是值类型,存储在栈内存中,每次赋值都是一次复制的过程

       var a = 12;        var b = a;

二. 引用类型数据拷贝

1、浅拷贝

只拷贝对象的一层数据,再深处层次的引用类型value将只会拷贝引用 实现方式:

1.Object.assign() 和 ES6的拓展运算符

通常我们用 Object.assign() 方法来实现浅拷贝。 Object.assign()用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。

  let aa = {                a: undefined,                 func: function(){console.log(1)},                 b:2,                 c: {x: 'xxx', xx: undefined},                d: null,                e: BigInt(100),                f: Symbol('s')        }        let bb = Object.assign({}, aa) //  或者 let bb = {...aa}        aa.c.x = 111        console.log(bb)        // 第一层拷贝,遇到引用类型的值就会只拷贝引用        // {        //     a: undefined,        //     func: [Function: func],        //     b: 2,        //     c: { x: 111, xx: undefined },        //     d: null,        //     e: 100n,        //     f: Symbol(s)        // }

2.Object.create

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。Object.create(proto,[propertiesObject])接收两个参数一个是新创建对象的__proto__, 一个属性列表

  let aa = {                a: undefined,                 func: function(){console.log(1)},                 b:2,                 c: {x: 'xxx', xx: undefined},        }        let bb = Object.create(aa, Object.getOwnPropertyDescriptors(aa))        aa.c.x = 111        console.log(bb)        // 第一层拷贝,遇到引用类型的值就会只拷贝引用        // {        //     a: undefined,        //     func: [Function: func],        //     b: 2,        //     c: { x: 111, xx: undefined },        // }

2、深拷贝

在拷贝一个对象的时候为了避免修改对数据造成的影响,必须使用深拷贝。

实现方式:

1、 通过JSON.stringify()

    var a = {a:1, b: 2}    var b = JSON.stringify(a);    a.a = 'a'    console.log(a, b) // { a: 'a', b: 2 } {"a":1,"b":2}

JSON.stringify()进行深拷贝有弊端: 忽略value为function, undefind, symbol, 并且在序列化BigInt时会抛出语法错误:TypeError: Do not know how to serialize a BigInt

// 序列化function, undefind, symbol,忽略--------------------------------------------------------        var obj = {                a:function(){},                 b: undefined,                 c: null,                 d: Symbol('s'),         }    var objCopyed = JSON.stringify(obj);        console.log("a:", a)     // obj: { a: [Function: a], b: undefined, c: null, d: Symbol(s) }    console.log("objCopyed:", objCopyed)     // objCopyed: {"c":null}// 序列化bigint抛出错误--------------------------------------------------------    var obj = {            a: 1,            e: BigInt(9007199254740991)    }    var objCopyed = JSON.stringify(obj); // TypeError: Do not know how to serialize a BigInt

2、递归实现

const deepCopy = (obj) => {        // 优化 把值类型复制方放到这里可以少一次deepCopy调用        // if(!obj || typeof obj !== 'object') throw new Error("请传入非空对象")    if(!obj || typeof obj !== 'object') return obj    let result = {}    if (Object.prototype.toString.call(obj).indexOf('Array') > 0) {        result = []    }    // 另一种循环方式    // for (let key in obj) {    //     if (obj.hasOwnProperty(key)) {    //        result[key] = deepClone(obj[key])     //     }    // }    Object.keys(obj).forEach(key => {            // 优化 把值类型复制方放到这里可以少一次deepCopy调用            // if (obj[key] && typeof obj[key] === 'object') {        //     result[key] = deepCopy(obj[key])        // }else{        //     result[key] = obj[key]        // }        result[key] = deepCopy(obj[key])    });    return result}let aa = {        a: undefined,         func: function(){console.log(1)},         b:2,         c: {x: 'xxx', xx: undefined},        d: null,        e: BigInt(100),        f: Symbol('s')}let bb = deepCopy(aa)aa.c.x = 123aa.func = {}console.log("aa", aa)console.log("bb", bb)// aa {//     a: undefined,//     func: {},//     b: 2,//     c: { x: 123, xx: undefined },//     d: null,//     e: 100n,//     f: Symbol(s)//  }// bb {//     a: undefined,//     func: [Function: func],//     b: 2,//     c: { x: 'xxx', xx: undefined },//     d: null,//     e: 100n,//     f: Symbol(s)// }

到此,关于"JS怎么实现深拷贝和浅拷贝"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0