【问题标题】:Serializing a Child Object Within a Parent Object in JavaScript在 JavaScript 中序列化父对象中的子对象
【发布时间】:2012-03-12 16:06:01
【问题描述】:

这个问题是我上一个问题的后续问题: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>

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

谢谢!

【问题讨论】:

  • 你真的是要把data 放在原型链中吗?这将使每个实例共享数据。
  • 没有。我不完全知道我在做什么。我试图理解这个面向对象的 JavaScript 东西。我来自 C# 背景。我假设这种方法创建了实例级变量。我错了吗?我该如何解决?
  • @user208662 Alnitak 上面提到的是您在另一篇帖子中接受的答案有什么问题;)

标签: javascript serialization


【解决方案1】:

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

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

要修复,请在this.init() 函数中将数据添加到this

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() 构造函数采用可选的完整初始值对象来代替默认值。

【讨论】:

  • 感谢您的回复。但是,这仍然不允许我在“MyChild”上调用“test”函数。例如,如果我执行“storedParent.data.children[0].test()”,我会收到 TypeError。
  • 啊,是的,没注意到那部分。您遇到的问题是反序列化数据会重新创建数据,但不会将对象附加到其原型。我会看看我是否可以修复小提琴来实现这一目标。
  • 感谢您的坚持。对于我的生活,我无法弄清楚。
  • 我刚刚注意到你解决了它。说真的,我不能说谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
  • 2017-10-05
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
相关资源
最近更新 更多