2

我正在序列化和存储从 WinJS.Class 创建的对象,如下所示:

var myClass = WinJS.Class.define(...);
var myObject = new myClass();
var serialized = JSON.stringify(myObject);
//store the object

后来我将对象从存储中取出,我想反序列化它并将其转换为myClass. 开箱即用的 WinJS 是否可行,或者我是否需要为我的类创建一个构造函数,该构造函数能够获取一个可以将其转换为新对象的对象?

我还没有进入 TypeScript,我认为在这种情况下会有所帮助,但在那之前我想知道如何使用普通的 JavaScript/WinJS 来做到这一点。

4

5 回答 5

1

有几种方法可以处理这个问题,没有一种对 WinJS 来说特别特别。简单来说:JSON 序列化只对对象值进行序列化和反序列化,而不是对其方法、原型或其他类型信息进行序列化和反序列化。

选项 1:将值复制到类的新实例 这通常最好通过让构造函数将反序列化对象作为参数并将数据复制到新实例来完成。

这有多种变体。使用对象构造函数通常是性能最好的,因为这通常使 JS 引擎能够对对象应用更多的优化。

WinJS.UI.setOptions 在这里可能会有所帮助,或者您可以使用这样的简单循环复制数据:

var keys = Object.keys(source);
for (var i = 0, len = keys.length; i < len; i++) {
    var key = keys[i];
    destination[key] = source[key];
}

选项 2:设置 __proto__ 警告:这可能会对性能产生显着的不利影响,因此在某些情况下不合适。但有时它会很方便。

Object.setPrototypeOf(myObject, myClass.prototype);

请注意, setPrototypeOf 相对较新。它在 Win8.1 上用于 Web 应用程序(我猜这是关于)和 IE 11,但在 Safari 中不可用,例如。在较旧的浏览器/Safari 上,分配给proto是等效的(但如果可用, setPrototypeOf 更好)。

这会将 myClass 中的方法附加到对象,但除了负面的性能影响之外,它也不会在对象上运行您的构造函数 - 因此它可能仍然与您最初序列化的对象处于不同的状态。

其他有用的东西:JSON“revivers” JSON.parse 采用可选的第二个参数,称为“reviver”。这使您可以提供一个函数,该函数有机会转换正在反序列化的 JSON 的每个节点。例如,这对于将序列化的日期重新合成为 JavaScript Date 对象很有用。它还有机会转换最顶层的对象,这在某些情况下可能有助于将反序列化的对象转换为您想要的“类”。

于 2015-04-26T23:56:57.223 回答
0

Javascript 是一种动态语言,所以我认为您不需要强制转换反序列化的对象,只需将其视为 myClass 类型即可。希望它可以帮助你。

于 2013-05-28T20:39:11.800 回答
0

您应该考虑使用“选项”构造函数模式,其中选项值是反序列化的对象:

// MovieModel Constructor
// ----------------------
function MovieModel(options) {
    this._titleValue = options.title || "Sample Title";
}

电影方法闭包是这样的:

// MovieModel Methods
// ------------------
var movieModelMethods = {
    title: {
        get: function () {
            return this._titleValue;
        },
        set: function (val) {
            this._titleValue = val;
            this.dispatchEvent("title");
        }
    }
};
于 2013-08-08T22:00:18.827 回答
0

由于WinJS类定义只能指定一个构造函数(据我了解),您可以使用静态成员定义一个工厂函数,它将序列化数据作为参数。这个工厂方法实际上会创建一个新实例,并将值一个一个设置并返回新对象。

它有一些优点,例如您可以随着增强应用程序的时间实际管理数据结构的变化......缺点是你不能一直编写 new MySuperClass() ......

...
// let's suppose we already called JSON.parse(data);
create: function(serializedData) {
    var newObj = new MySuperClass();
    newObj.name = serializedData.name || "";
    newObj.color = serializedData.color || "";
    return newObj;
}

然后你会在应用程序的其他地方调用:

var myInstance = MySuperClass.create(serializedDataFromfile);
于 2015-04-25T09:33:26.387 回答
-2

您应该能够在将 JSON.parse 从本地存储中拉出后调用它:

变量 myObject2; myObject2 = JSON.parse(localStorage["mySeriazliedObject"];

于 2013-01-21T02:17:40.323 回答