【问题标题】:JSON.stringify missing superclass properties when using a subclass with Spine使用带有 Spine 的子类时 JSON.stringify 缺少超类属性
【发布时间】:2012-10-31 11:39:06
【问题描述】:

我看到在 Spine 中针对子类模型使用 JSON.stringify 时出现了奇怪的行为,我希望有人能提供帮助!

以下是我们在一个项目中获得的一些代码的简化摘录:

define([
    "jquery",
    "underscore"
],

function ($, _) {
    var SuperClass = Spine.Model.sub();
    SuperClass.configure("SuperClass", "SuperClassProperty");

    var SubClass = SuperClass.sub();
    SubClass.configure("SubClass", "SubClassProperty");

    var instance = new SubClass({ SuperClassProperty: "Super", SubClassProperty: "Sub" });
    console.log(instance);

    var json = JSON.stringify(instance);
    console.log(json);
});

“console.log(instance)”正在打印出我在这种情况下所期望的内容:

result
    SubClassProperty: "Sub"
    SuperClassProperty: "Super"
    cid: "c-0"
    __proto__: ctor

但是,当我对实例使用 JSON.stringify 时,这就是我返回的全部内容:

{"SubClassProperty":"Sub"} 

为什么 SuperClassProperty 不包含在 stringify 中?

我通过强制 JSON2 覆盖 Chrome 的原生 JSON 对象,排除了 JSON.stringify 方法的问题;两种实现都产生相同的结果。看起来 stringify 将委托给对象上的“toJSON”函数(如果有的话)——在这种情况下有(作为 Spine 的一部分)。

所以看起来(a)这是 Spine 中的一个错误,或者(b)我做错了,这是更有可能的选择。

我知道我也可以通过在子类上重新配置超类属性来解决这个问题:

SubClass.configure("SubClass", "SuperClassProperty", "SubClassProperty");

但这对我来说似乎违反直觉(子类化有什么意义?),所以我希望这不是答案。

更新:我已经通过 Spine 源代码进行了一些调试,据我所知,问题在于我配置子类的方式:

    var SubClass = SuperClass.sub();
    SubClass.configure("SubClass", "SubClassProperty");

在这里调用“配置”似乎会清除 SuperClass 中的属性。 Model原型上的“toJSON”实现如下:

Model.prototype.toJSON = function() {
    return this.attributes();
};

由于在配置 SubClass 时会重置属性集合,因此在 JSON 字符串中不会出现 SuperClass 属性。

我不确定我是否不应该在子类对象上调用“配置”,但我在文档中找不到任何地方说我应该做其他事情 - 这是我能找到的唯一参考子类化模型(来自:http://spinejs.com/docs/models):

模型也可以很容易地被子类化:

var User = Contact.sub();
User.configure("User");

【问题讨论】:

  • 我不知道 Spine 是如何工作的,但JSON.stringify 只查看可枚举的“自己的属性”,而不是继承或不可枚举的属性。如果你这样做会发生什么:console.log(Object.keys(instance)); 在结果数组中,你得到了 super 属性吗?
  • 好问题 - 但它是正确的:["SuperClassProperty", "SubClassProperty", "cid"]
  • 奇怪。那是原生的Object.keys 方法吗?如果你这样做instance.hasOwnProperty("SuperClassProperty")会发生什么?还有Object.getOwnPropertyDescriptor(instance, "SuperClassProperty")
  • 您好,感谢您的帮助! Object.keys 是原生的; instance.hasOwnProperty 返回 true;并且 getOwnPropertyDescriptor 为“SuperClassProperty”和“SubClassProperty”返回相同的东西(当然是不同的值)。
  • 您在 Firefox 中是否也遇到过这个问题,或者只是在 Chrome 中?

标签: javascript json requirejs spine.js


【解决方案1】:

正如我所怀疑的,问题出在我使用 Spine 的方式上。 This comment from the author of Spine 推断在子类上使用“配置”将消除超类的属性。我不得不承认我不明白为什么会这样;这对我来说似乎违反直觉,但至少我现在知道这不是错误。

万一其他人遇到这个问题,我解决它的方法是将我自己的扩展方法添加到 Spine 模型中,如下所示:

(function () {
    var Model = Spine.Model;

    Model.configureSub = function () {
        var baseAttributes = this.attributes.slice();
        this.configure.apply(this, arguments);

        this.attributes = baseAttributes.concat(this.attributes);
        return this;
    };
})();

现在配置我的子类:

var SubClass = SuperClass.sub();
SubClass.configureSub("SubClass", "SubClassProperty");

现在我的 JSON 正确反映了超类和子类的属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-13
    • 2020-07-05
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多