如何在JavaScript中序列化一个对象?

20

例如,我有一个类:

function Test() {
}

Test.prototype = {
    'setTest' : function(test) {
        this.test = test;
    }
}
var test = new Test();
Test.setTest('test');

我想将对象test保存在数据库中。 如何将对象test序列化为字符串?(包括方法、变量等)


12
应该使用test.setTest("test"),而不是Test.setTest("test") - Šime Vidas
6个回答

16

使用 JSON 简单易懂

JSON.stringify( test );

55
JSON.stringify()方法不会序列化方法。 - MrTrick

11
在这种情况下,对于您提出的问题,真正想要做到您所需的是没有办法的。您请求的问题在于“序列化附加到对象的所有内容,包括函数”。
通常仅针对数据进行序列化,因为可执行文件通常是机器绑定的,也就是说它们是针对特定计算机编译的,基于某些特征。现在,可以说JavaScript函数只需要JavaScript解释器,因为JavaScript是一次编写,到处运行。但是当人们编写串行化程序时,因为所有串行化程序 tend 可以工作相同,我们仅针对数据进行编写。在这种情况下,行业标准是JSON,这是一个仅针对对象数据的序列化程序。
此时有三个解决方案可供选择:
1.编写自己的序列化程序/反序列化程序,封装函数。这可能很棘手,因为并非所有JavaScript引擎都会向您提供源代码访问权限。 2.编写自己的重新加载机制,生成特定的新初始化类型,并将类型名称保存为序列化中的一个属性。这样,每个变量的初始化都会给您提供方法,然后与数据合并就可以得到完整的对象。 3.将每个函数存储为字符串,并根据需要实时评估它。这非常棘手,并且容易出错。我想不出任何情况可以变得有用,因为它非常脆弱。但这是一个选择,不能被忽视。
我知道3是1的子答案,所以您可以把它看作只有两个有用的答案。
我知道表面上这在Chrome和IE9上可以工作,因此它应该可以在大多数用户可能使用的地方工作。
var abc = function(thing) { return thing; }
abc.toString();
// gives "function(thing) { return thing; }" on the command line

你肯定可以将方法序列化为字符串替代实际方法,但是你需要创建一个副本对象以便能够捕获源对象上的每个元素(我认为是这样做,而不是在原地替换它们)。

希望这可以帮助你更好地思考问题,也许让你意识到你没有必要将方法序列化(我所知道的人都没有这样做,也不合理)。


2
闭包对上下文的引用使得这更加困难:如果“thing”是一个局部变量而不是参数,并且abc被返回到一个不再拥有thing的外部作用域。 - bsb

3

最好的方法是编写自己的序列化方法,根据你的getter创建一个带有属性的JSON对象。通常情况下,你为每个属性定义一个getter方法。这样就可以适用于大多数情况(因此不必为每个类定义一个serialize方法)。

function serialize(obj) {
   var serialized = {};

   for(var prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
           if (/^get.*/.test(prop)) {
               var value = obj[prop]();
               var name = prop.replace('get', '');

               if (typeof value === 'object') {
                   serialized[name] = this.serialize(value);
                   continue;
               }

               serialized[name] = value;
           }
       }
   }

   return serialized;
};

如果您想将属性值重置回类中,您有两个选项:

  • 在您的类中创建一个函数,该函数基于序列化的JSON创建有效的对象实例。
  • 创建一个unserialize方法并使用setter方法将JSON映射到您的类中。

示例:

function unserialize(obj, emptyClass) {
   // Check emptyClass for setters and map the data from obj to it.
   return 'class instance';
}

2
通常情况下,您可以使用广泛支持的JSON来实现此目的,它支持跨浏览器/语言/库等。唯一的问题是JSON不支持函数 - 但你真的需要序列化那些函数吗?

0

我之前曾经支持过类似这样的功能。我最终将函数名称保存为字符串并将其序列化为JSON格式。然后当我回到客户端时,使用像this question中发布的帮助程序执行该函数。

如果有人有更好的解决方法,请告诉我!


-1

我最近不得不找到这个问题的解决方案。我相信它可以得到改进。

首先,我创建了一个用于实例化“可序列化”对象的模块。

function MyObj(serialised){
    this.val = "";
    if(serialised){
        var unserialised = JSON.parse(serialised);
        for (var i in unserialised) {
            this[i] = unserialised[i];
        }
    }
}

MyObj.prototype.myMethod = function () { return this.val;};

module.exports = MyObj;

当然,你必须考虑错误处理和其他验证。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接