javascript中嵌套对象的深度复制数组 [英] Deep copying array of nested objects in javascript

查看:39
本文介绍了javascript中嵌套对象的深度复制数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 javascript 中深度复制嵌套对象数组.我的阵列看起来像这样

I am trying to deep copy array of nested objects in javascript. My array look like this

var arr = [{name:"adam",age:"21"},
    {name:"freddie",age:"35",children:[{name:"mercury",age:"25"}]},
    {name:"jim",age:"35",children:[{name:"morrison",age:"25",children:[{name:"some", age:"40"}]}]}
    ];

我想对数组中的每个对象进行深层复制,即我想将 arr 的精确副本创建到不应具有对象引用的新数组中.数组的深度也是未知的,即子数组可以达到任何级别.我已经通过这个链接复制数组在javascript(深度复制) 中没有对象引用的对象到另一个数组,但这对我没有帮助.我在 jQuery 中搜索并找到了一些解决方案,但这对我没有帮助,因为我不了解 jQuery.

I want to make a deep copy of every object inside the array that is i want to create a exact copy of arr into new array which should not have object reference. Depth of array is also unknown that is children array can be upto any level. I have gone through this link Copying of an array of objects to another Array without object reference in javascript(Deep copy) but that did not help me. I googled and found some solutions in jQuery but that did not help me as i dont have knowledge of jQuery.

我也尝试用递归来实现它,但这也不起作用http://ideone.com/kJi5X3

I also tried implementing it with recursion but that's not working too http://ideone.com/kJi5X3

我只想在不使用 jQuery 或任何东西的情况下在 javascript 中完成它.我是 JavaScript 的新手,所以如果有任何库或简单的方法可以做到这一点,我可能会错过.请帮我解决这个问题.提前致谢.

I want to do it in javascript only without using jQuery or anything. I am new to JavaScript so i may have missed if there is any library or simple method to do this. Please help me to solve this problem. Thanks in advance.

推荐答案

您有两个主要选择:

  1. 使用JSON.stringifyJSON.parse:

var copy = JSON.parse(JSON.stringify(original));

但是我从不喜欢那样.文本往返是低效的,它不会正确处理 DateRegExpundefined 等值,除非你写一个替代者和一个复活者.

But I've never liked that. A round-trip through text is inefficient at best, and it won't handle Date, RegExp, undefined, etc. values correctly unless you write a replacer and a reviver.

使用递归函数,像这样:

Use a recursive function, something like this:

var toString = Object.prototype.toString;
function deepCopy(obj) {
    var rv;

    switch (typeof obj) {
        case "object":
            if (obj === null) {
                // null => null
                rv = null;
            } else {
                switch (toString.call(obj)) {
                    case "[object Array]":
                        // It's an array, create a new array with
                        // deep copies of the entries
                        rv = obj.map(deepCopy);
                        break;
                    case "[object Date]":
                        // Clone the date
                        rv = new Date(obj);
                        break;
                    case "[object RegExp]":
                        // Clone the RegExp
                        rv = new RegExp(obj);
                        break;
                    // ...probably a few others
                    default:
                        // Some other kind of object, deep-copy its
                        // properties into a new object
                        rv = Object.keys(obj).reduce(function(prev, key) {
                            prev[key] = deepCopy(obj[key]);
                            return prev;
                        }, {});
                        break;
                }
            }
            break;
        default:
            // It's a primitive, copy via assignment
            rv = obj;
            break;
    }
    return rv;
}
var a = [1, {foo: "bar"}, ['a', 'b'], new Date()];
snippet.log(JSON.stringify(a));
var b = deepCopy(a);
snippet.log(JSON.stringify(b));

<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

请注意,以上使用了所有现代浏览器上都存在的 ES5 功能,但不包括一些较旧的浏览器,例如 IE8.但是,对于旧版浏览器,上面使用的所有功能都可以使用 polyfill.

Note that the above uses ES5 features present on all modern browsers but not some older ones, like IE8. All of the features used above can be polyfilled, however, for older browsers.

这不会试图处理自定义构造函数或保留数组中对象的原型;这样做会使事情戏剧性变得更加复杂,如果没有关于如何调用这些构造函数进行复制操作的约定,就不可能做到完美.您可以通过分配相同的原型来接近,但这不会考虑构造函数中的逻辑,尤其是在其中设置为闭包的函数.

That doesn't try to get into handling custom constructor functions or preserving prototypes on objects in the array; doing so makes things dramatically more complicated and impossible to make perfect without a convention for how to call those constructors for a copy operation. You can get close by assigning the same prototype, but that wouldn't account for logic within the constructor function and in particular for functions set up as closures within it.

这篇关于javascript中嵌套对象的深度复制数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆