×

Vue3中如何实现深拷贝(Deep Copy)

提问者:Terry2025.04.19浏览:45

什么是深拷贝呀?为啥在Vue3里需要关注它呢?

嘿呀,深拷贝呢,简单说就是把一个对象完整地复制一份出来,新的对象和原来的对象在内存里是完全独立的,不管是修改新对象还是原来的对象,都不会互相影响哦。

在Vue3里就经常会用到深拷贝啦,比如说,咱们有个复杂的响应式数据对象,里面可能嵌套了好多层别的对象呀、数组啥的,要是直接赋值给一个新变量,那其实只是浅拷贝哦,新变量和原来的变量指向的还是同一块内存区域呢,这时候要是修改了新变量里面嵌套的某个值,原来的响应式数据也会跟着变啦,这可就不符合咱们有时候的预期咯,所以就需要深拷贝来搞出一个完全独立的副本来用呀。

Vue3里自带能直接用的深拷贝方法不?

哎呀,Vue3本身可没有专门提供一个特别现成的用来做深拷贝的方法哦,不过呢,JavaScript里有一些办法可以在Vue3项目里拿来实现深拷贝的效果啦。

那在Vue3项目里用啥办法能实现深拷贝呢?

  1. JSON.parse和JSON.stringify组合: 这可是个挺常用的小技巧哦,就像这样:

    let originalObj = {
     name: '小明',
     hobbies: ['画画', '唱歌'],
     address: {
         city: '北京',
         street: '某某街'
     }
    };

let copiedObj = JSON.parse(JSON.stringify(originalObj));

// 现在修改copiedObj里的值,不会影响originalObj啦 copiedObj.name = '小红'; copiedObj.hobbies.push('跳舞'); copiedObj.address.city = '上海';

console.log(originalObj); console.log(copiedObj);

不过呢,这个方法有个小缺点哦,就是它只能处理能被正确JSON序列化和反序列化的对象,要是对象里有函数呀、Symbol类型的值,或者有循环引用的情况(就是一个对象里的某个属性又指向了这个对象本身或者它的父对象之类的),那就会出问题啦,可能会得到不正确的结果或者直接报错呢。
2. **递归实现深拷贝**:
要是遇到上面那种JSON方法搞不定的情况,咱就可以自己动手写个递归函数来做深拷贝啦,大概思路是这样的哦:
```js
function deepCopy(obj) {
    if (obj === null || typeof obj!== 'object') {
        return obj;
    }
    let copiedObj;
    if (Array.isArray(obj)) {
        copiedObj = [];
        for (let i = 0; i < obj.length; i++) {
            copiedObj[i] = deepCopy(obj[i]);
        }
    } else {
        copiedObj = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                copiedObj[key] = deepCopy(obj[key]);
            }
        }
    }
    return copiedObj;
}
let originalObj = {
    name: '小明',
    hobbies: ['画画', '唱歌'],
    address: {
        city: '北京',
        street: '某某街'
    },
    someFunction: function() {
        console.log('我是个函数哦');
    }
};
let copiedObj = deepCopy(originalObj);
// 现在修改copiedObj里的值,不会影响originalObj啦
copiedObj.name = '小红';
copiedObj.hobbies.push('跳舞');
copiedObj.address.city = '上海';
copiedObj.someFunction = function() {
    console.log('我是新函数啦');
};
console.log(originalObj);
console.log(copiedObj);

这个递归函数呢,就会一层一层地把对象或者数组里面的每个元素都复制出来,遇到对象就继续递归进去复制它里面的属性,这样就能实现比较完美的深拷贝啦,就算对象里有函数之类的特殊情况也能处理好哦,不过要注意呀,写递归函数得小心别搞出栈溢出的情况,要是对象嵌套太深了,就可能会出问题,得合理调整一下代码逻辑或者做些优化呢。

  1. 使用第三方库: 还有个省心的办法就是用一些第三方库啦,像Lodash就有个_.cloneDeep方法可以很方便地实现深拷贝哦。 首先得安装Lodash呀,在项目里运行npm install lodash。 然后就可以这样用啦:

    import _ from 'lodash';

let originalObj = { name: '小明', hobbies: ['画画', '唱歌'], address: { city: '北京', street: '某某街' } };

let copiedObj = _.cloneDeep(originalObj);

// 现在修改copiedObj里的值,不会影响originalObj啦 copiedObj.name = '小红'; copiedObj.hobbies.push('跳舞'); copiedObj.address.city = '上海';

console.log(originalObj); console.log(copiedObj);

Lodash的这个方法功能挺强大的,能处理很多复杂的情况,而且经过了很多优化,一般用起来挺靠谱的呢。
**四、啥时候该选哪种深拷贝方法呀?**
如果你的对象比较简单,就是些基本数据类型组成的,没有函数呀、Symbol这些特殊的东西,也没有循环引用的情况,那用JSON.parse和JSON.stringify组合就挺方便快捷的啦。
要是你的对象可能会有函数呀、或者不太确定会不会有一些特殊情况,那自己写个递归函数实现深拷贝就比较保险咯,虽然要多写点代码,但是能应对各种复杂情况嘛。
而如果你不想自己费那么多事儿写代码,又希望有个很靠谱能处理各种复杂情况的深拷贝方法,那就果断选择用像Lodash这样的第三方库的方法呀,简单又好用呢。
总之呢,在Vue3里实现深拷贝得根据具体的对象情况和项目需求来选择合适的方法哦,这样才能让咱们的代码稳稳当当,不出啥意外情况啦。

您的支持是我们创作的动力!

网友回答文明上网理性发言 已有0人参与

发表评论: