使用JSON打包和解压缩复杂的对象体系结构

时间:2012-03-10 02:00:41

标签: javascript json html5 local-storage

我一直在研究HTML 5的新本地存储,到目前为止看起来很酷。我决定使用JSON将我的对象序列化为字符串并将它们解析回对象,这听起来非常好。然而,说起来容易做起来难。我发现你不能只是JSON.stringify()一个物体并期望它能很好地为你包装,但我无法弄明白我必须做什么。

但并非所有这些:我的对象包含两个数组,每个数组包含另一种类型的对象,其中一个是多维的。这是我相当复杂和相互依赖的对象架构的样子:

function Vector2(x, y) {
    this.x = x;
    this.y = y;
}

function Bar(ID, position) {
    this.id = id;
    this.position = position;
}

function Goo(state, position) {
    this.on = state;
    this.position = position;
}

function Foo(name, size) {
    this.name = name;
    this.size = size;
    this.bars = new Array(width)
    this.goos = new Array(10);

    this.Initialize();
}

Foo.prototype.Initialize() {
    for(var x = 0;x<this.size.x;x++) {
            this.bars[x] = new Array(this.size.y);

        for(var y=0;y<this.size.y;y++) {
            this.bars[x][y] = new Bar(x + y, new Vector2(x, y));
        }
    }

    for(var i = 0;i<this.goos.length;i++) {
        this.goos[i] = new Goo(on, new Vector2(i, i/2 + 1));
    }
}

这些对象中的每一个都有很多附加功能,每个都使用我用来将方法添加到Foo的相同原型方法添加。就像我说的那样复杂。我的问题是,如何序列化所有这些?我是否真的需要将toJSON()函数添加到每个对象?

最后,一旦我将所有这些打包并保存到localstorage,我知道如何检索它,但我对如何用JSON解压缩它几乎一无所知。不过,这又是另一回事了,而且我怀疑一旦我学会如何把所有东西都收拾起来,我自己可能会更容易理解。

注意:我通常不会提出这样一个潜在的广泛问题,但我真的无法在SO上找到任何东西,或者我真的找不到任何真正解决这个问题的谷歌,而且我不知道如何进一步打破这个问题。

4 个答案:

答案 0 :(得分:2)

通常,你不只是在javascript中序列化复杂的数据结构,因为正常的序列化不能处理多个不同的东西,它们都引用了同一个对象,无法处理循环引用等等......

我建议的是你弄清楚应用程序的真实状态是什么。不是整个实例化的对象结构,而是重建数据状态实际需要的最小信息量。然后,一旦你弄明白了(它应该只是数据,没有实际的对象),那么你可以创建函数或方法从数据结构中获取数据或从数据中创建新的数据结构。

在查看代码时,Foo对象的实际状态是Bar个对象的二维数组和Goo个对象的一维数组以及{{1}和namesize只有Barxy。 Goo只有idstate以及x。编写一个生成Foo方法和从保存的存储中接受该状态的Foo方法,这将是非常容易的状态。

答案 1 :(得分:1)

处理toJSON和fromJSON函数可能是正确的方法。您应该只将任何给定对象的实际唯一数据保存为JSON,因为几个重要原因序列化整个实例化对象不是一个好主意,#1只是不必要。另外,请考虑在不久的将来为一个对象添加或修改函数的情况:存储了自己的序列化对象的客户端永远不会获得更新。只需存储唯一的实例数据,并具有将数据转换回真实对象的功能(使用您最近的定义)即可。

答案 2 :(得分:0)

您可以将函数打包到字符串:

var a = function() {return "a"};
a.toString()

// And also:

function b() {return "b"};
b.toString();

因此,从那里你可以破解JSON源(由Douglas Crockford提供)并包含对函数的支持。或者其他什么。

答案 3 :(得分:0)

我希望我不会太晚,但我遇到了同样的问题。

我想将一个promise对象(从JQuery AJAX调用返回)保存到本地存储。

幸运的是,我偶然发现了一个名为Stash(http://rezitech.github.io/stash/)的小Javascript库。它既可以将复杂Javascript对象序列化为Strings,也可以将String解析为Javascript对象。

最好的事情是,您不必显式执行序列化/解析,因为当您想要将对象保存到本地存储/从本地存储检索对象时,会自动识别和转换数据类型。

这是一个产生积极结果的快速测试

// the api endpoint

var url = "www.api-host.com/api/bla/blub";

// create json call returning promise object

var promise = $.getJSON(url);

// persist promise object in local storage using dash.js

var key = url;

stash.set(key, promise);

// retrieve promise object from local storage

var stashGet = stash.get(key);

// display in console

console.log(stashGet);

问候,马蒂亚斯