JavaScript:Deep Copy Circular JSON [英] JavaScript: Deep Copy Circular JSON

查看:93
本文介绍了JavaScript:Deep Copy Circular JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写深层复制方法,但需要跟踪我访问过的节点,以便我可以链接到之前的 visitedNode 而不是永久深度复制,直到堆栈溢出。

I'm trying to write a deep copy method, but need to keep track of my visited nodes, so that I can link to the previously visitedNode instead of deep copying forever until stack overflow.

var visitedNodes = {};
var obj = {}; obj.a = obj;   // circular; can't use JSON.stringify)
var obj2 = {};

visitedNodes[obj] = "should need key obj (not obj2) to access this string";

console.log(visitedNodes[obj2]);    // logs the string unfortunately

我没有一种存储内存位置的独特方式 - 它存储在 [object Object] ,我不能使用JSON.stringify,因为它是一个循环结构

I don't have a unique way of storing the memory location -- it stores itself at [object Object] and I can't use JSON.stringify because it's a circular structure

我尝试使用 var visitedNodes = new Map(); 但仍然没有骰子

I tried using var visitedNodes = new Map(); but still no dice

我目前的方法是利用 Array.prototype.indexOf 函数,但我不知道是否也适用于圆形结构,因为我这里也有堆栈溢出!!!

My current approach is to utilize the Array.prototype.indexOf function, but I don't know if it works with circular structures either, because I'm getting a stack overflow here too!!!

this.clone = function (item, visitedNodes) {
    visitedNodes = visitedNodes || [];
    if (typeof item === "object" && !Array.isArray(item)) {
        if (visitedNodes.indexOf(item) === -1) {
            var cloneObject = {};
            visitedNodes.push(cloneObject);
            for (var i in item) {
                if (item.hasOwnProperty(i)) {
                    cloneObject[i] = this.clone(item[i], visitedNodes);
                }
            }
            return cloneObject;
        } else {
            return visitedNodes[visitedNodes.indexOf(item)];
        }
    }
    else if (typeof item === "object" && Array.isArray(item)) {
        if (visitedNodes.indexOf(item) === -1) {
            var cloneArray = [];
            visitedNodes.push(cloneArray);
            for (var j = 0; j < item.length; j++) {
                cloneArray.push(this.clone(item[j], visitedNodes));
            }
            return cloneArray;
        } else {
            return visitedNodes[visitedNodes.indexOf(item)];
        }
    }

    return item; // not object, not array, therefore primitive
};






问题:



任何人都有任何获取唯一内存地址的想法,以便我可以确定我之前是否参加过Object的参考?我相信我可以构建一个基于 Object.keys() Object.prototype.constructor 的唯一哈希,但这似乎荒谬,如果构造函数相同且子键与父键相同,则会给出误报


the question:

Anyone have any ideas for getting a unique memory address so I can determine if I've been to the Object's reference before? I believe I could construct a unique hash based off Object.keys() and Object.prototype.constructor but that seems absurd and will give false positives if constructor is the same and the child keys are the same as the parent

推荐答案

在visitedNodes中保存原始引用,并创建另一个数组以使用相同的索引保存克隆对象时使用的时候是一个引用。

In visitedNodes save the original reference, and create another array to save with same index the clone object to use when is a reference.

function deepClone(obj) {
    var visitedNodes = [];
    var clonedCopy = [];
    function clone(item) {
        if (typeof item === "object" && !Array.isArray(item)) {
            if (visitedNodes.indexOf(item) === -1) {
                visitedNodes.push(item);
                var cloneObject = {};
                clonedCopy.push(cloneObject);
                for (var i in item) {
                    if (item.hasOwnProperty(i)) {
                        cloneObject[i] = clone(item[i]);
                    }
                }
                return cloneObject;
            } else {
                return clonedCopy[visitedNodes.indexOf(item)];
            }
        }
        else if (typeof item === "object" && Array.isArray(item)) {
            if (visitedNodes.indexOf(item) === -1) {
                var cloneArray = [];
                visitedNodes.push(item);
                clonedCopy.push(cloneArray);
                for (var j = 0; j < item.length; j++) {
                    cloneArray.push(clone(item[j]));
                }
                return cloneArray;
            } else {
                return clonedCopy[visitedNodes.indexOf(item)];
            }
        }

        return item; // not object, not array, therefore primitive
    }
    return clone(obj);
}

var obj = {b: 'hello'};
obj.a = { c: obj };
var dolly = deepClone(obj);
obj.d = 'hello2';
console.log(obj);
console.log(dolly);

代码运行示例:
http://jsbin.com/favekexiba/1/watch?js,console

这篇关于JavaScript:Deep Copy Circular JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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