【问题标题】:How to serialize an object in JavaScript?如何在 JavaScript 中序列化对象?
【发布时间】:2020-05-11 04:05:10
【问题描述】:

例如我有课:

function Test() {
}

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

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

【问题讨论】:

  • 应该是test.setTest("test"),而不是Test.setTest("test")

标签: javascript node.js


【解决方案1】:

简单的json

JSON.stringify( test );

【讨论】:

  • JSON.stringify() 不序列化方法。
【解决方案2】:

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

序列化通常只发生在数据上,因为可执行文件通常是机器绑定的,因为它们是为给定的机器编译的,基于某些特征。现在,可以合理地说 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

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

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

【讨论】:

  • 对上下文的闭包使这更加困难:如果“thing”是一个本地变量而不是一个参数,并且 abc 被返回到一个不再有这个东西的外部范围。
【解决方案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';
}

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      我以前必须支持类似的功能。我最终将函数的名称保存为字符串并将其序列化为 JSON。然后当我回到客户端时,我使用一个帮助器来执行这个函数,就像在this question 中发布的那个。

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

      【讨论】:

        【解决方案6】:

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

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

        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;
        

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

        【讨论】:

          猜你喜欢
          • 2011-04-06
          • 1970-01-01
          • 2018-07-15
          • 1970-01-01
          • 2020-07-12
          • 1970-01-01
          • 2023-03-03
          • 1970-01-01
          相关资源
          最近更新 更多