1

Web ブラウザと Node.js バックエンドで使用したい Javascript ライブラリがあります。ライブラリには、メソッドが次のように定義された複数のオブジェクトがあります。

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/ )

基本的に、これよりも良い方法はありますか?

私のオブジェクトの多くには、独自のメソッドで作成した他のオブジェクトのインスタンスが含まれています。クライアントとサーバーの両方が同じライブラリとオブジェクト定義を使用するため、オブジェクトごとにコンストラクターを作成するのは面倒なようです。JavaScript がプロトタイプに基づいていることは知っていますが、JavaScript を使い始めたばかりで Python やクラスベースの言語に慣れているため、よくわかりません。

助けてくれてありがとう!

4

1 に答える 1

1

JSON.stringifyメソッドを持つオブジェクトのみを文字列化しますtoJSONtoJSONしたがって、メソッドをメソッドに追加するだけです。(関数もオブジェクトであることを忘れないでください。)

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); }"}"

ただし、これを解析すると、関数が文字列として取得されます。したがって、次のような方法で文字列を関数に戻す必要があります。

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

ただし、このように JavaScript をいじる代わりに、now.jsのような十分にテストされたライブラリを使用することをお勧めします。

于 2012-12-19T08:52:41.190 に答える