1

我有一个 Javascript 库,我想在 Web 浏览器和 Node.js 后端使用它。在库中,我有多个对象,其方法定义如下:

function foo() {
  this.bar = 200;
  this.someMethod = function(baz) {
    return this.bar + baz;
  };
}

var x = new foo();

我可以通过执行以下操作在客户端或 Node.js 服务器中使用它:

x.someMethod(5);
   => (returns 205)

现在,当我JSON.stringify是我的对象时,它会在没有方法的情况下显示出来。

var string = JSON.stringify(x);
   => {"bar":200}

这意味着我无法在我的服务器上解压缩 JSON 并使用相同的方法。

var parsed = JSON.parse(string);
document.write(parsed.someMethod(5));
   => (doesn't do anything. the methods are gone!)

在基于类的系统中,我只使用复制构造函数。可以从 JSON 重建对象的东西。

function foo_copy_constructor(parsed_json) {
  f = new foo();
  f.bar = parsed_json.bar;
  return f;
}

var z = foo_copy_constructor(parsed);
z.someMethod(5);
   => (returns 205 like it should)

(jsfiddle:http: //jsfiddle.net/7FdDe/

基本上,还有比这更好的方法吗?

Many of my objects contain instances of other objects I've written with their own methods, and this seems like it would get tedious to build a constructor for every object since both the client and the server use the same library and object definitions. I know that JavaScript is based on prototypes, but I don't really understand them since I've just started with JavaScript and am used to Python and class-based languages.

Thanks for any and all help!

4

1 回答 1

1

JSON.stringify only stringifies the objects that have the toJSON method. So you could simply add the toJSON method to your methods. (Remember, functions are objects too.)

function A() {
    this.method = function() { console.log(1); };
}

var c = new A();
JSON.stringify(c);
"{}"

A.prototype.otherMethod = function() { console.log(1); };

var c = new A();
JSON.stringify(c);
"{}"

Function.prototype.toJSON = function() { return this.toString(); };
JSON.stringify(c);
"{"method":"function () { console.log(1); }"}"

However, when parsing this back, you get the function as a string. So you have to the strings back to functions with something like this:

var d = JSON.parse(JSON.stringify(c));
Object.keys(d).forEach(function(k) {

    // If it starts with "function"
    if (/^function/.test(d[k])) {

        // Get the body of the function
        var f = d[k].match(/{(.*)}/).pop();

        // Replace the string with a real function
        d[k] = new Function(f);
    }
});

d.method();
1

However, instead of messing with javascript like this, I'd rather suggest that you use a well-tested library like now.js.

于 2012-12-19T08:52:41.190 回答