在Node.js中将JS对象(包括方法)写入文件?

9

我看到了如何按照这里描述的方式将对象写入文件: 如何在Node.js中将对象保存到文件中? 但是否有一种方法可以将对象写成一种方式,使我能够重新加载该对象到内存中,包括其方法?


2
编写和读取函数存在注入的巨大风险。我会考虑这个决定的安全影响。 - anthony sottile
我同意安东尼的观点。不过,如果你真的需要它,你可以简单地保存JavaScript代码,然后加载它并调用eval函数。 - freakish
我同意安全方面的顾虑。我只是在玩一个想法。谢谢! - luisgo
3个回答

6
如@AnthonySottile之前所说,这可能极其危险,我不确定是否有任何好的使用情况,但只是为了好玩而已,您需要编写自己的递归序列化程序。类似于这样:
var toString = Object.prototype.toString;

function dump_object(obj) {
    var buff, prop;
    buff = [];
    for (prop in obj) {
        buff.push(dump_to_string(prop) + ': ' + dump_to_string(obj[prop]))
    }
    return '{' + buff.join(', ') + '}';
}

function dump_array(arr) {
    var buff, i, len;
    buff = [];
    for (i=0, len=arr.length; i<len; i++) {
        buff.push(dump_to_string(arr[i]));
    }
    return '[' + buff.join(', ') + ']';
}

function dump_to_string(obj) {
    if (toString.call(obj) == '[object Function]') {
        return obj.toString();
    } else if (toString.call(obj) == '[object Array]') {
        return dump_array(obj);
    } else if (toString.call(obj) == '[object String]') {
        return '"' + obj.replace('"', '\\"') + '"';
    } else if (obj === Object(obj)) {
        return dump_object(obj);
    }
    return obj.toString();
}

这个方法可以处理大多数类型的数据,但总有一些奇怪的情况会破坏它,因此我不建议在生产环境中使用。反序列化的方法如下:

eval('var test = ' + dump_to_string(obj))

5
为什么要重复造轮子?定义toJSON方法以自定义对象的序列化,例如<SomeObject>.prototype.toJSON。为了更灵活,可以定义一个替换器(replacer)用于JSON.stringify - Rob W
@RobW 不知道这两个,非常有用,谢谢! - Trevor
dump_to_string函数的replace功能必须是全局的,例如: obj.replace(/"/g, '\"') 我提供了一次编辑,但可能被拒绝了,不知道 :) - jaywink
1
同意@jaywink的观点,obj.replace 应该使用 /"/g 来确保所有的 " 都被正确替换,而不仅仅是第一个。 - Chris Houghton
1
这个答案已经给出4年了,但它刚刚救了我!你让我的一天!非常感谢你!!! - Katia

2
这段话的大意是:这个问题很老了,但我找不到任何简单有效的 JavaScript 序列化方案。可以使用 BSON(MongoDB 内部对象表示法),它使用二进制格式来表示内存中的对象。虽然我找不到文档链接,但代码有很好的文档记录,我能给出类似这样的代码。
fs = require 'fs'
bson = require('bson').BSONPure.BSON

obj = {
  string: "test",
  func: (s) ->
    console.log s
}

fs.writeFile 'test.txt', bson.serialize(obj, false, false, true), (err) ->
  return console.log("Err : #{err}") if err
  fs.readFile 'test.txt', (err, file) ->
    return console.log("Err : #{err}") if err
    deserialized = bson.deserialize file, evalFunctions: true
    deserialized.func deserialized.string // Outputs 'text', as expected

这是coffee-script,但代码简单易懂,适合所有人理解。

小心使用“evalFunctions: true”选项,因为它将允许JavaScript执行(请参见https://gist.github.com/DinisCruz/245716893d783ea740ea) - Dinis Cruz

0

我最近编写了shoveJS: https://shovemedia.github.io/shovejs/ 来处理这种情况。YMMV -- 我还没有尝试过在Node中使用它。

它将一个类型化的对象结构转换为JSON(然后您可以将其保存到磁盘上),并且可以将该结构膨胀回包括正确的对象->对象引用等在内的类型化对象。需要明确的是,方法/类定义本身不会被序列化。系统只是期望在序列化期间可用的已注册的Model / Factory类也在反序列化期间可用。

提前道歉,我没有发布一些简单的示例。

编辑:该技术是Rob W在下面评论中提到的升级版。


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