JavaScript序列化和方法

JavaScript序列化和方法,javascript,json,serialization,Javascript,Json,Serialization,我不熟悉“面向对象”JavaScript。目前,我有一个需要在页面间传递的对象。我的对象定义如下: function MyObject() { this.init(); } MyObject.prototype = { property1: "", property2: "", init: function () { this.property1 = "First"; this.property2 = "Second"; },

我不熟悉“面向对象”JavaScript。目前,我有一个需要在页面间传递的对象。我的对象定义如下:

function MyObject() { this.init(); }
MyObject.prototype = {
    property1: "",
    property2: "",

    init: function () {
        this.property1 = "First";
        this.property2 = "Second";
    },

    test: function() {
      alert("Executing test!");
    }
}
在我的应用程序的第1页,我正在创建MyObject的一个实例。然后我序列化对象并将其存储在本地存储器中。我正在这样做,如下所示:

var mo = new MyObject();
mo.test();                                    // This works
window.localStorage.setItem("myObject", JSON.stringify(mo));
现在,在第2页,我需要得到那个对象并使用它。要检索它,我使用以下命令:

var mo = window.localStorage.getItem("myObject");
mo = JSON.parse(mo);
alert(mo.property1);    // This shows "First" as expected.
mo.test();              // This does not work. In fact, I get a "TypeError"  that says "undefined method" in the consol window.

根据输出,当我序列化对象时,函数不知何故被删除了。我仍然可以看到酒店。但是我不能与我的任何功能交互。我做错了什么?

JSON不序列化函数

请看第二段

如果需要保留这些值,可以在序列化时或在反序列化之前转换值,以使JSON能够表示其他数据类型

换句话说,如果您真的想对函数进行JSONify,可以在序列化之前将其转换为字符串:

mo.init = ''+mo.init;
mo.test = ''+mo.test;
在反序列化之后,将它们转换回函数

mo.init = eval(mo.init);
mo.test = eval(mo.test);

但是,没有理由这样做。相反,您可以让您的
MyObject
构造函数接受一个简单的对象(解析JSON字符串的结果)并将对象的属性复制到自身。

这是因为我认为
JSON.stringify()
不会序列化函数

函数不能序列化为JSON对象

因此,我建议您为实际属性创建一个单独的对象(或对象中的属性),并将此部分序列化。 之后,您可以实例化对象及其所有函数,并重新应用所有属性以重新获得对工作对象的访问权

按照您的示例,这可能如下所示:

function MyObject() { this.init(); }
MyObject.prototype = {
    data: {
      property1: "",
      property2: ""
    },

    init: function () {
        this.property1 = "First";
        this.property2 = "Second";
    },

    test: function() {
      alert("Executing test!");
    },


   save: function( id ) {
     window.localStorage.setItem( id, JSON.stringify(this.data));
   },
   load: function( id ) {
     this.data = JSON.parse( window.getItem( id ) );
   }

}

你说得对,函数会被删除。此页面可能有助于:


“不包括在JSON中没有表示形式的值(例如函数和未定义的值)。

为了避免更改结构,我更喜欢在对象检索时使用
Object.assign
方法。此方法将第二个参数对象合并到第一个参数对象中。为了得到对象方法,我们只需要一个空的新对象作为目标参数

var mo = window.localStorage.getItem("myObject");
// this object has properties only
mo = JSON.parse(mo);
// this object will have properties and functions
var completeObject = Object.assign(new MyObject(), mo);
请注意,
Object.assign
的第一个参数由函数修改并返回

看起来当我序列化对象时,函数不知何故被删除了。。。我做错了什么

是的,当使用
JSON.stringify()
JSON.parse()
时,函数将被删除,并且代码中没有任何错误

为了在序列化和反序列化过程中保留函数,我制作了一个名为的npm模块来解决这个问题——JavaScript类实例值将在序列化过程中以纯JSON格式保存在第1页上,以及它的类名信息:

var ESSerializer = require('esserializer');

function MyObject() { this.init(); }
MyObject.prototype = {
    property1: "",
    property2: "",

    init: function () {
        this.property1 = "First";
        this.property2 = "Second";
    },

    test: function() {
      alert("Executing test!");
    }
}
MyObject.prototype.constructor=MyObject; // This line of code is necessary, as the prototype of MyObject has been overridden above.

var mo = new MyObject();
mo.test();                                    // This works
window.localStorage.setItem("myObject", ESSerializer.serialize(mo));
稍后,在第2页的反序列化阶段,esserializer可以递归地反序列化对象实例,并保留所有类型/函数信息:

var mo = window.localStorage.getItem("myObject");
mo = ESSerializer.deserialize(mo, [MyObject]);
alert(mo.property1);    // This shows "First" as expected.
mo.test();              // This works too.

哇!这太优雅了。我喜欢它。非常感谢您的分享。您能提供一个例子吗?也许是一杯鸡尾酒?短暂性脑缺血发作