web-dev-qa-db-ja.com

toJSON()とJSON.Stringify()の違い

モデルのすべてのデータ属性を読み取りまたは複製する必要がある場合は、そのtoJSON()メソッドを使用します。このメソッドは、属性のコピーをオブジェクトとして返します(名前にもかかわらずJSON文字列ではありません)。 (JSON.stringify()がtoJSON()メソッドでオブジェクトに渡されると、元のオブジェクトではなくtoJSON()の戻り値を文字列化します。前のセクションの例では、JSON.stringifyを呼び出すときにこの機能を利用しました。 ()モデルインスタンスをログに記録します。)

http://addyosmani.github.io/backbone-fundamentals/#backbone-basics

JSON表記のrepresenting an objectのこれら2つの方法の違いを教えてください。これらが同じことを達成するのか、それとも違いがあるのか​​、私はただ混乱しています。

48
Shane

ファインマニュアル から:

toJSON動作

文字列化されているオブジェクトに値が関数であるtoJSONという名前のプロパティがある場合、toJSONメソッドはJSON文字列化の動作をカスタマイズします。シリアル化されるオブジェクトの代わりに、toJSONメソッドが呼び出されると、シリアル化されます。

これが、Backboneがシリアル化に toJSON メソッドを使用し、mというモデルインスタンスが指定されている理由です。

_var string = JSON.stringify(m);
_

サーバーが気にしないノイズの束ではなく、mから属性のみを取得します。

とはいえ、主な違いは、toJSONがJSON文字列に変換される値(数値、ブール値、オブジェクトなど)を生成するのに対し、_JSON.stringify_は常に文字列を生成することです。

デフォルトのバックボーンtoJSON はこれだけです(モデルの場合):

_return _.clone(this.attributes);
_

m.toJSON()は、モデルの属性のshallowコピーを提供します。属性値として配列またはオブジェクトがある場合、予期しない参照共有を終了します。 _Backbone.Model#clone_ にも注意してください この問題に苦しんでいます

モデルのデータを安全に複製したい場合は、_JSON.stringify_を介して送信してから、_JSON.parse_を送信してディープコピーを取得できます。

_var data         = JSON.parse(JSON.stringify(model_instance));
var cloned_model = new M(data);
_

ここで_model_instance_は、バックボーンモデルMのインスタンスです。

51
mu is too short
  • JSON.stringify()-有効なJSON表現値はすべて文字列化できます。

    JSON.stringify(..)ユーティリティは、undefinedfunction、およびsymbolの値に遭遇すると、それらを自動的に省略します。そのような値がarrayで見つかった場合、その値はnullに置き換えられます(そのため、配列の位置情報は変更されません)。 objectのプロパティとして見つかった場合、そのプロパティは単に除外されます。

    JSON文字列化には、object値にtoJSON()メソッドが定義されている場合、シリアル化に使用する値を取得するためにこのメソッドが最初に呼び出されるという特別な動作があります。

  • toJSON()-文字列化に適した有効なJSON値へ。

    1つの例、JSON.stringify()およびobjectに循環参照が含まれる場合、エラーがスローされます。 toJSON()は次のように修正できます。

    var o = { };
    var a = {
        b: 32,
        c: o
    };
    
    // circular reference
    o.d = a;
    
    // JSON.stringify( a ); // an error caused by circular reference
    
    // define toJSON method
    a.toJSON = function() {
         return { b: this.b };
    };
    
    JSON.stringify( a ); // "{"b":32}"
    
10
zangw

また、Addy Osmaniの Developingbackbone.jsアプリケーション も読んでいますが、同じ質問があります。コンソールで彼の例を試してみました(todoリスト)。

var Todo = Backbone.Model.extend({
    defaults:{
         title:"",
         completed:false
}
});

var todo1 = new Todo(); 


console.log(todo1.toJSON())
//The console shows
//Object {title: "finish your assignment", completed: false}

console.log(JSON.stringify(todo1))
//The console shows
//{"title":"finish your assignment","completed":false}
3
Lijie Zhou