在JavaScript中对父对象内的子对象进行序列化

时间:2012-03-12 16:06:01

标签: javascript serialization

这个问题是我上一期提问的后续问题:JavaScript Serialization and Methods。虽然相关,我相信这是不同的,这就是我开始这个线程的原因。无论...

我有一个复杂的对象树,我需要在页面之间传递。因此,我正在尝试序列化和反序列化我的对象。特别是我的一个对象有几个子对象集合。这些子对象类型中的每一个都有一个函数,我正在尝试调用它。不幸的是,我没有运气。我设置了一个测试项目,试图找出问题并找到问题的根源。目前,我在一个名为objects.js的单独文件中定义了我的JavaScript对象。那个文件看起来像这样:

objects.js

function MyChild() { this.init(); }
MyChild.prototype = {
    data: {
        id: 0,
        fullName: "",
    },

    init: function () {

    },

    save: function (key) {

    },

    load: function (key) {

    },

    test: function () {
        alert("Testing Child functions");
    }
}

function MyParent() { this.init(); }
MyParent.prototype = {
    data: {
        id: "",
        children: null
    },

    init: function () {
        this.data.children = [];
    },

    save: function (key) {
        window.localStorage.setItem(key, JSON.stringify(this.data));
    },

    load: function (key) {
        var temp = window.localStorage.getItem(key);
        if (temp != null) {
            this.data = JSON.parse(temp);
            $.each(this.data.children, function (i, r) {
            });
        }
    },

    test: function () {
        alert("Testing Parent functions");
    }
}

我正在创建,序列化,反序列化以及尝试与.html文件中的这些对象进行交互。这个.html文件显示在这里:

的test.html

<div>
    <input id="button1" type="button" value="Create Object Tree" onclick="button1Click();" /><br />
    <input id="button2" type="button" value="Retrieve and Execute" onclick="button2Click();" /><br />
</div>

<script type="text/javascript">
    function button1Click() {
        var child = new MyChild();
        child.data.id = 1;

        var p = new MyParent();
        p.data.id = "A";
        p.data.children.push(child);
        p.save("A");
    }

    function button2Click() {
        var storedParent = new MyParent();
        storedParent.load("A");

        storedParent.test();                          // This works
        alert(storedParent.data.children.length);     // This displays "1" like I would expect
        alert(storedParent.data.children[0].data.id); // This does NOT work. 
        storedParent.data.children[0].test();         // This does NOT work.   
    }
</script>

我不确定我做错了什么。有人可以帮我理解这个吗?可以somone请帮我修复我的例子。我有一种预感,我没有正确地序列化MyChild对象。但我不明白我应该如何序列化/反序列化它们与MyParent。

谢谢!

1 个答案:

答案 0 :(得分:2)

您需要将data存储在每个对象中,而不是prototype内。

存储在对象prototype中的数据在所有实例之间共享,不会被JSON.stringify序列化,因此您的对象数据永远不会在本地存储中结束。

要修复此问题,请在this函数中向this.init()添加数据:

MyChild.prototype = {
    init: function() {
        this.data = {
            id: 0,
            fullName: ""
        };
    },
    ...
}

MyParent.prototype = {
    init: function() {
        this.data = {
            id: "",
            children: []
        }
    },
    ...
}

http://jsfiddle.net/alnitak/fdwVB/

的工作样本

请注意,将MyChild中的函数附加到检索到的数据非常棘手。以下代码似乎有效:

load: function(key) {
    var temp = window.localStorage.getItem(key);
    if (temp != null) {
        this.data = JSON.parse(temp);
        var children = this.data.children;
        for (var i = 0; i < children.length; ++i) {
            children[i] = $.extend(new MyChild(), children[i]);
        }
    }
},

但请注意,它的工作原理是为每个检索到的条目构建一个新的“默认”子级,然后用序列化的值覆盖该子级的数据。

如果构造函数具有“副作用”,则可能会出现问题。

更好的方法可能是允许MyChild()构造函数使用可选的初始值对象而不是默认值。