深拷贝、浅拷贝的区别?如何实现深拷贝和浅拷贝?

基本类型的数据赋值后,更改赋值后的变量,两者互不影响

let a = 100;
let b = a;
a = 200;

console.log(a); // 200
console.log(b); // 100

引用类型的数据赋值后,将存放在栈内存中的地址赋值给新变量,更改赋值后的变量会影响到原数据

复制代码
// 复杂数据类型:Array、Object
let obj1 = {
    name:"小李",
    age:18
    }

let obj2 = obj1
obj1.age = 25;

console.log( obj1 );     // {name:"小李", age:25}
console.log( obj2 );     // {name:"小李", age:25}
复制代码

深浅拷贝的目的就是原对象改变不影响新拷贝对象的结果

浅拷贝

定义:

  • 创建一个新对象,这个对象有着原始数据值的一份拷贝
  • 如果是基本数据类型,拷贝的就是基本类型的值
  • 如果是引用数据类型,拷贝的就是内存地址,如果改变了这个地址就会影响到另一个对象

浅拷贝只能实现一层的拷贝,无法实现深层次的拷贝

实现方法:
Object.assign()第一个参数是拷贝目标,剩下的参数是拷贝的源对象(可以是多个)

复制代码
let obj1 = {
    name: "小李",
    age: 18
}
// Object.assign()  会返回一个新对象 

// 这种写法和下面写法实现效果一样
// let obj2 = Object.assign({}, obj1)

let obj2 = {}
Object.assign(obj2, obj1)
obj1.name = '小张';
obj1.age = '25';

console.log(obj1); // {name:"小张", age:25}
console.log(obj2); // {name:"小李", age:18}
复制代码

contact()合并两个或多个数组,返回一个新数组。原数组不变

let arr = [1,2,3,4];
let newArr = arr.concat()
arr.push(5);

console.log(arr);        // [1,2,3,4,5]
console.log(newArr );    // [1,2,3,4]

扩展运算符(如果对象中的属性都是基本数据类型的话,使用扩展运算符更加方便)

复制代码
let obj1 = {
    name: "小李",
    age: 18
}
let obj2 = {...obj1}

obj1.name = '小张';
obj1.age = '25';
console.log(obj1, obj2);


let arr = [1, 2, 3]
let newArr = [...arr]
arr[0] = 999
console.log(arr, newArr)
复制代码

深拷贝

不管原数据内的值是什么类型,新拷贝的数据和原数据都是相互独立的,没有关联

实现方法

利用josn数据和josn字符串之间的转换(无法拷贝对象中的方法)

JSON.stringify() 将对象转换成JSON字符串

JSON.parse() 反序列化将JSON字符串变成一个新的对象

复制代码
let obj1 = {
    name: "小李",
    age: 18,
    father: {
        age: 40
    },
    fn: function () {
        return 123
    }
}
let temp = JSON.stringify(obj1)
let obj2 = JSON.parse(temp)

obj1.father.age = 50;

console.log(obj1);         // {name:"小李", age:18, father:{age:50},fn()}
console.log(obj2);         // {name:"小张", age:25, father:{age:40}}
console.log(obj2.fn)     // underfind
复制代码

$.extend()

jQuery.extend([deep], target, object1, [objectN])

deep默认为false;

target新的对象

object1及后面的为要拷贝的对象

复制代码
// 注意要引入jQuery的CDN才能使用该方法
let obj1 = {
    name: "小李",
    age: 18,
    father: {
        age: 40
    },
    fn: function () {
        return 123
    }
}

let obj2 = $.extend(true, {}, obj1)

obj1.father.age = 50;

console.log(obj1,obj2);
复制代码

递归

复制代码
function deepClone(obj) {
    // 定义一个对象,用来确定当前的参数是数组还是对象
    let objClone = Array.isArray(obj) ? [] : {};
    // 判断obj是否存在,且类型是对象。(typeof [] 也是 object)
    if (obj && typeof obj === "object") {
        // 遍历参数的键
        for (key in obj) {
            // hasOwnProperty() 方法不会检测对象的原型链,只会检测当前对象本身存在该属性时才返回 true,常与for...in使用
            // 判断对象是否存在该属性
            if (obj.hasOwnProperty(key)) {
                // 值是对象就递归
                if (obj[key] && typeof obj[key] === "object") {
                    objClone[key] = deepClone(obj[key]);
                } else {
                    // 基本数据类型  直接赋值
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}
let a = {
    name: "小李",
    age: 18,
    father: {
        name: "大李",
    },
    fn: function () {
        return 123
    }
}
let b = deepClone(a)
a.father.name = "小李他爸"

console.log(a, b);
复制代码

 

posted @   天青色等烟雨灬  阅读(211)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示