在线客服

ES6 - 深拷贝与浅拷贝

adminadmin 报建百科 2024-04-24 153 11
ES6 - 深拷贝与浅拷贝

使用Object.assign()拷贝对象存在的问题

Object.assign()实现的是浅拷贝

// 对基本数据类型没有问题,但是对引用数据类型的时候有些属性就会丢掉,如属性g
let target = {
    a: {
        b: {
            c: 1
        },
        e: 4,
        f: 5,
        g: 6
    }
}

let source = {
    a: {
        b: {
            c: 1
        },
        e: 2,
        f: 3
    }
}

console.log(Object.assign(target,source));

基本数据类型中简单的深拷贝

当a发生变化的时候b并没有随着a发生变化,这叫深拷贝,2个值不相互影响

let a = 5
let b = a
a = 6
console.log(a,b);                  // 6 5

对象的浅拷贝

// 浅拷贝:obj1和obj2在内存中存的是相同的内存地址
let obj1 = {
    name: 'lee',
    age: '32'
}
let obj2 = obj1
obj1.age = 18
console.log(obj1);              // {name: 'lee', age: 18}
console.log(obj2);             // {name: 'lee', age: 18}

如何改为深拷贝

1.使用JSON.parse()JSON.stringfy()

让obj1 和 obj2 不相互干扰,实现深拷贝

使用JSON.parse()JSON.stringfy()实现深拷贝(不支持对函数进行深拷贝)

  • JSON.parse(): 将JSON字符串转成对象

  • JSON.stringfy():将对象转成字符串

思路:先用 JSON.stringfy()将对象转成字符串,再使用SON.parse()转成对象

// obj1中的age值发生变化,但是obj2并不受影响
let obj1 = {
    name: 'lee',
    age: '32'
}

let str = JSON.stringify(obj1)
let obj2 = JSON.parse(str)
obj1.age = 18
console.log(obj2);                // {name: 'lee', age: '32'}

上面obj1和obj2是2个独立的对象,再堆内存中存的是2个不同的内存地址,因此它们彼此不相互干扰

2.使用递归自己实现一个深拷贝的函数(适用于基本数据类型、数组和对象)

如何判断数据类型 - 通过toString()方法判断数据类型

typeOf()只能判断基本数据类型,不能判断引用数据类型

let checkType = data =>{
    console.log(Object.prototype.toString.call(data)); 
}
checkType([])        // "[object Array]"

通过对象原型上的tosString方法得到数据类型的字符串形式,下面还需对这个字符串进行截取,只想要Array

let checkType = data =>{
    console.log(Object.prototype.toString.call(data).slice(8,-1)); 
}
checkType([])      // Array

使用递归实现深拷贝

let checkType = data => {
    return Object.prototype.toString.call(data).slice(8, -1);
}

let deepClone = source => {
    let sourceType = checkType(source)
    let result
    if(sourceType === 'Object'){
        result = {}
    }else if(sourceType === 'Array'){
        result = []
    }else{
       return source
    }
    for(let i in source){
        let value = source[i]
        let valueType = checkType(value)
        if(valueType === 'Object' || valueType === 'Array'){
            // 递归
            result[i] = deepClone(value)
        }else{
            result[i] = value
        }
    }
    return result
}
// arr1值的改变不影响arr2
let arr1 = {name:'lee',age:18}
let arr2 = deepClone(arr1)
arr1.age = '32'
console.log(arr1);      // {name:'lee',age:32}
console.log(arr2);     // {name:'lee',age:18}

// obj1值的改变不影响obj2
let obj1 = {
    name: 'lee',
    like:['读书','打游戏']
}
let obj2 = deepClone(obj1)
obj1.like[0] = '跑步'
console.log(obj1);     // 
console.log(obj2);

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!
代办报建

本公司承接江浙沪报建代办施工许可证。
联系人:张经理,18321657689(微信同号)。

喜欢0发布评论

11条评论

  • 游客 发表于 2个月前

    好无聊啊!http://jalv.cqyiyou.net/test/053491490.html

  • 游客 发表于 2个月前

    帖子很有深度!http://qwl.sy00066.com

  • 游客 发表于 1周前

    有品位!http://www.guangcexing.net/voddetail/mCZAaPYjzS.html

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址