17

例如我有课:

function Test() {
}

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

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

4

6 回答 6

16

简单的 json

JSON.stringify( test );
于 2012-08-01T13:33:27.103 回答
9

在这种情况下,对于您提出的问题,确实没有办法做您想做的事。您的请求的问题在于“序列化附加到对象的所有内容,包括函数”。

序列化通常只发生在数据上,因为可执行文件通常是机器绑定的,因为它们是基于特定特征为给定机器编译的。现在,可以合理地说 javascript 函数只需要一个 javascript 解释器,因为 javascript 是一次写入,到处运行。但是当人们编写序列化器时,因为所有序列化器的工作方式都一样,我们只为数据编写它们。在这种情况下,行业标准是 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

因此,您当然可以将方法序列化为字符串来代替实际方法,但是您将需要创建一个重复的对象,以便您可以捕获源对象上的每个元素(我认为,而不是替换它们)。

希望这可以帮助您更多地考虑问题,并可能意识到您不需要序列化方法(据我所知,没有人这样做,不合理)。

于 2012-08-01T14:33:11.777 回答
3

最好的方法是编写您自己的序列化方法,该方法根据您的 getter 创建一个具有属性的 JSON 对象。通常,您为每个属性定义一个 getter。所以它应该适用于大多数情况(所以你不必为每个类定义一个序列化方法)。

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 创建一个有效的对象实例。
  • 创建一个反序列化方法并使用设置器将 JSON 映射到您的类。

例子:

function unserialize(obj, emptyClass) {
   // Check emptyClass for setters and map the data from obj to it.
   return 'class instance';
}
于 2015-09-19T17:26:22.170 回答
1

通常,您会使用JSON来执行此操作,它在浏览器/语言/库/等中得到广泛支持。唯一的问题是 JSON 不支持函数——但你真的需要序列化这些函数吗?

于 2012-08-01T13:07:02.387 回答
0

我以前必须支持与此类似的功能。我最终将函数的名称保存为字符串并将其序列化为 JSON。然后,当我回到客户端时,我使用这个问题中发布的帮助程序执行该功能。

如果有人有更好的方法来解决这个问题,我想看看!

于 2012-08-01T13:09:36.083 回答
-2

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

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

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;

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

于 2015-07-31T21:59:58.473 回答