23

関数であるオブジェクトのメンバーを含む、ブラウザー間で Javascript オブジェクトを文字列にシリアル化 (およびシリアル化解除) するソリューションを探しています。典型的なオブジェクトは次のようになります。

{
   color: 'red',
   doSomething: function (arg) {
        alert('Do someting called with ' + arg);
   }
}

doSomething() にはローカル変数のみが含まれます (呼び出しコンテキストをシリアル化する必要もありません!)。

JSON.stringify() は関数であるため、「doSomething」メンバーを無視します。toSource() メソッドが私が望むことを行うことはわかっていましたが、それは FF 固有です。

4

5 に答える 5

8

手早く汚れた方法は次のようになります。

Object.prototype.toJSON = function() {
  var sobj = {}, i;
  for (i in this) 
    if (this.hasOwnProperty(i))
      sobj[i] = typeof this[i] == 'function' ?
        this[i].toString() : this[i];

 return sobj;

};

for in明らかに、これはコード内のすべてのオブジェクトのシリアル化に影響し、フィルター処理されていないループを使用してナイーブ コードをつまずかせる可能性があります。「適切な」方法はtoJSON、循環参照などを処理して、特定のオブジェクトのすべての子孫メンバーに関数を追加する再帰関数を作成することです。ただし、シングル スレッド Javascript (Web ワーカーなし) を想定すると、このメソッドは機能し、意図しない副作用は発生しません。

同様の関数を Array のプロトタイプに追加して、オブジェクトではなく配列を返すことによって Object のプロトタイプをオーバーライドする必要があります。別のオプションは、単一のものをアタッチし、オブジェクト自体の性質に応じて配列またはオブジェクトを選択的に返すようにすることですが、おそらく遅くなります。

function JSONstringifyWithFuncs(obj) {
  Object.prototype.toJSON = function() {
    var sobj = {}, i;
    for (i in this) 
      if (this.hasOwnProperty(i))
        sobj[i] = typeof this[i] == 'function' ?
          this[i].toString() : this[i];

    return sobj;
  };
  Array.prototype.toJSON = function() {
      var sarr = [], i;
      for (i = 0 ; i < this.length; i++) 
          sarr.push(typeof this[i] == 'function' ? this[i].toString() : this[i]);

      return sarr;
  };

  var str = JSON.stringify(obj);

  delete Object.prototype.toJSON;
  delete Array.prototype.toJSON;

  return str;
}

http://jsbin.com/yermateno/2/edit

于 2010-09-10T15:19:27.457 に答える
1

オブジェクト自体の助けなしでは不可能です。たとえば、この式の結果をどのようにシリアル化しますか?

(関数 () {
  var x;
  戻る {
      get: 関数 () { return x; }、
      設定: 関数 (y) { return x = y; }
    };
})();

関数のテキストを取得するだけの場合、逆シリアル化xすると、クロージャー内の変数ではなく、グローバル変数が参照されます。また、関数がブラウザーの状態 (div への参照など) で終了する場合、それが何を意味するかを考える必要があります。

もちろん、他のオブジェクトへの参照に必要なセマンティクスをエンコードする、個々のオブジェクトに固有の独自のメソッドを作成することもできます。

于 2010-09-17T17:34:00.643 に答える
1

JSONfn プラグインはまさにあなたが探しているものです。

http://www.eslinstructor.net/jsonfn/

--ヴァディム

于 2013-08-01T01:26:26.090 に答える
1

このようなもの...

(function(o) {
    var s = "";
    for (var x in o) {
        s += x + ": " + o[x] + "\n";
    }
    return s;
})(obj)

注:これは表現です。引数として渡されたオブジェクトの文字列表現を返します (私の例では、obj という名前の変数に を渡しています)。

オブジェクトのプロトタイプの toString メソッドをオーバーライドすることもできます。

Object.prototype.toString = function() {
    // define what string you want to return when toString is called on objects
}
于 2010-09-10T15:34:59.967 に答える