ホームページ  >  記事  >  ウェブフロントエンド  >  JSON.stringify() の使用法の概要

JSON.stringify() の使用法の概要

巴扎黑
巴扎黑オリジナル
2017-08-18 10:55:292388ブラウズ

経験豊富なユーザーの皆様、JSON.stringify には 2 番目と 3 番目のオプションのパラメーターがあることをご存知ですか?彼らは何ですか?信じられないような気がしませんか?次の記事では、JSON.stringify について、あまり知られていない関連情報をサンプル コードを通じて詳しく紹介します。必要な方は参考にしてください。

はじめに

JSON は徐々に XML に取って代わり、世界中の開発者によって広く使用されています。この記事では、JavaScript での JSON.stringify の使用の詳細について詳しく説明します。まず、JSON と JavaScript について簡単に説明します。

  • すべての合法的な JSON が有効な JavaScript であるわけではありません。

  • JSON の数値は 10 進数です。

  • 1. JSON.stringify

let foo = { a: 2, b: function() {} };
JSON.stringify(foo);
// "{ "a": 2 }"

JSON.stringify 関数は、JavaScript オブジェクトをテキストの JSON に変換します。テキスト化できないプロパティは無視されます。 foo の属性 b の値は関数定義であり、変換されずに失われます。


他に変換できない属性は何ですか?

1. 循環参照

オブジェクトの属性値が何らかの間接的な方法でオブジェクト自体を指している場合、それは循環参照です。例:

var bar = {
 a: {
  c: foo
 }
};
var foo = {
 b: bar
};

属性 c がそれ自体を指している場合、レイヤーごとに分析すると、無限ループに入ります。これを印刷して見てみましょう:


let fooStringified = JSON.stringify(foo);
console.log(fooStringified); // {"b":{"a":{}}}

c の属性は foo オブジェクトを指しており、foo オブジェクトの b 属性は bar オブジェクトを指しており、オブジェクト全体が無視され、処理できません。空のオブジェクトが返されます。


次の定義 (原文の例) はコンパイルできません:

let foo = {b : foo};

エラーメッセージ:


ReferenceError: foo is not defined
 at repl:1:14

関数型言語 Haskell では、Lazy Evaluation 技術により、同様の定義方法が可能です。使用済み 。


2. シンボルと未定義

let foo = { b: undefined };
JSON.stringify(foo);
// {}
// Symbols
foo.b = Symbol();
JSON.stringify(foo);
// {}

例外


配列では、文字列化できない要素は null で埋められます。

let foo = [Symbol(), undefined, function() {}, 'works']
JSON.stringify(foo);
// "[null,null,null,'works']"

これにより、配列自体の「形状」、つまり各要素の元のインデックスを維持できます。


一部の属性を文字列化できないのはなぜですか?

JSON は普遍的なテキスト形式であり、言語とは何の関係もないからです。関数定義も文字列化されている場合、それがどの言語であるかを判断し、適切な方法で表示する方法が特に複雑になることを想像してください。特に、JavaScript のシンボルなど、言語に関連するいくつかの機能。 ECMASCript 関係者は、この点も特に強調しました:

ECMAScript の内部データ表現を他のプログラミング言語に強制しようとするものではなく、代わりに、ECMAScript のテキスト表現の小さなサブセットを他のすべてのプログラミング言語と共有します

2。オブジェクトの toJSON 関数をオーバーライドする

オブジェクトの特定のプロパティを文字列化できないことを回避する方法は、オブジェクトの toJSON メソッドを実装して、文字列化されるオブジェクトをカスタマイズすることです。ほぼすべての AJAX 呼び出しで JSON.stringify が使用されるため、このテクニックを習得すると、サーバーとの対話を処理する際に非常に役立ちます。 オブジェクト内の要素を文字列の形式で返すことができる toString と同様に、toJSON は、文字列化できないオブジェクト内の属性を変換するメソッドを提供します。これにより、次回の JSON.stringify の呼び出しで属性を変換できるようになります。 JSON形式。

function Person (first, last) {
 this.firstName = first;
 this.last = last;
}
 
Person.prototype.process = function () {
 return this.firstName + ' ' +
   this.lastName;
};
 
let ade = new Person('Ade', 'P');
JSON.stringify(ade);
// "{"firstName":"Ade","last":"P"}"

Person インスタンス ade の処理関数は stringify ではありません。サーバーが姓と名をそれぞれ取得する代わりに、ade のフルネームのみを必要としていると仮定すると、目的を達成するために toJSON を直接定義できます:


Person.prototype.toJSON = function () {
 return { fullName: this.process(); };
};
 
let ade = new Person('Ade', 'P');
JSON.stringify(ade);
// "{"fullName":"Ade P"}"

toJSON を定義する利点は再利用性と安定性です。 ade と一致する可能性があります。使用されるライブラリの場合、転送されるデータは toJSON 定義によって返される fullName になります。


// jQuery
$.post('endpoint', ade);
 
// Angular 2
this.httpService.post('endpoint', ade)


3. オプションのパラメータ

JSON.stringify の完全な定義は次のとおりです:

JSON.stringify(value, replacer?, space?)

replacer と space は両方ともオプションのパラメータです。次に、それらを個別に説明します。


Replacer

replacer は、文字列化する属性名を含むフィルター関数または配列です。定義されていない場合、すべてのプロパティはデフォルトで文字列化されます。

1. 配列

配列内の属性のみが文字列化されます:

let foo = {
 a : 1,
 b : "string",
 c : false
};
JSON.stringify(foo, ['a', 'b']);
//"{"a":1,"b":"string"}"

ネストされた属性もフィルターされます:


let bar = {
 a : 1,
 b : { c : 2 }
};
JSON.stringify(bar, ['a', 'b']);
//"{"a":1,"b":{}}"
 
JSON.stringify(bar, ['a', 'b', 'c']);
//"{"a":1,"b":{"c":2}}"

フィルター配列の定義はニーズを満たさない場合があります。機能をカスタマイズできます。


2. 関数

フィルター関数は、オブジェクト内のすべての属性と値を入力として受け取り、戻り値には次のような状況があります。

未定義を返すことは、属性を無視することを意味します。 、ブール値または数値は文字列化されます

  • 基本型のプロパティが見つかるまで、再帰呼び出しがトリガーされます。

  • 返回无法stringify的值将会被忽略;


let baz = {
 a : 1,
 b : { c : 2 }
};
 
// 返回大于1的值
let replacer = function (key, value) {
 if(typeof === 'number') {
  return value > 1 ? value: undefined;
 }
 return value;
};
 
JSON.stringify(baz, replacer);
// "{"b":{"c":2}}"

通过改写上面的函数加入适当的输出,可以看到具体的执行步骤:


let obj = {
 a : 1,
 b : { c : 2 }
};
 
let tracer = function (key, value){
 console.log('Key: ', key);
 console.log('Value: ', value);
 return value;
};
 
JSON.stringify(obj, tracer);
// Key:
// Value: Object {a: 1, b: Object}
// Key: a
// Value: 1
// Key: b
// Value: Object {c: 2}
// Key: c
// Value: 2

space

你是否意识到调用默认的JSON.stringify返回的值只要一行,而且完全没有空格?如果想要更加美观的打印出来,那么就需要使用space这个参数了。

我告诉你一个非常简单的方法:通过tab(‘\t')来分割即可。


let space = {
 a : 1,
 b : { c : 2 }
};
 
// 使用制表符
JSON.stringify(space, undefined, '\t');
// "{
// "a": 1,
// "b": {
// "c": 2
// }
// }"
 
JSON.stringify(space, undefined, '');
// {"a":1,"b":{"c":2}}
 
// 自定义分隔符
JSON.stringify(space, undefined, 'a');
// "{
// a"a": 1,
// a"b": {
// aa"c": 2
// a}
// }"

一道三颗星的思考题:为什么打印结果的倒数第三行有两个a呢?

结论

本文介绍了一些使用toJSON的技巧:

  • 无法stringify的几种类型

  • 使用toJSON来自定义JSON.stringify的属性

  • 可选参数replacer的两种定义方法来过滤属性

  • 可选参数space用来格式化输出结果

  • 数组和对象中如果包含无法stringify的元素的时候的区别

以上がJSON.stringify() の使用法の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。