JSON 形式 (JavaScript Object Notation と略称) は、記述が簡単なデータ交換用のテキスト形式です。
ネイティブ JavaScript 構文に基づいて、オブジェクト、配列、数値、文字列、ブール値、および null をシリアル化できます。
ES5 では、JSON 形式のデータを処理するために特別に使用される JSON オブジェクトが追加されました。
JSON はオブジェクトですが、メソッドは と の 2 つだけで、parse
コンストラク stringify
ターとして使用できず、プロパティもありません。
typeof JSON === 'object'
JSON.parse
JSON.parse()
JSON 文字列を解析して、対応する JavaScript 値またはオブジェクトを取得するために使用されます。
JSON.parse('{}') // {}
JSON.parse('true') // true
JSON.parse('null') // null
JSON.parse 構文
JSON.parse(text[, reviver])
- text: 解析される文字列。
数値が渡されると、10 進数の出力に変換されます。
ブール値が渡された場合は、直接出力されます。
null が渡された場合は、null が出力されます。
他のタイプの値はサポートされていません。それ以外の場合は、エラーが報告されます。 - reviver: オプションのコンバーター。解析によって生成された元の値を変更するために使用できます。
戻り値: JavaScript オブジェクト/値、指定された JSON テキストに対応するオブジェクト/値。
リバイバーパラメータ
reviver 関数は、解析された JavaScript 値を変換および処理し、処理後に最終結果を返すために使用されます。
変換プロセス:
key
解析された値自体とそれに含まれる可能性のあるすべての属性は、特定の走査順序に従って reviver 関数と呼ばれ、属性の名前と 値が 2 つのパラメーターとして渡されますvalue
。
走査順序: レベルに従って、内側から外側に走査し、最終的に解析された値自体である最上位レベルに到達します。- reviver が未定義を返した場合、オブジェクトは削除され、別の値が返された場合、その値は現在のプロパティの新しい値になります。
- 最上位レベルに移動する場合、属性がないため、パラメータ キーは空の文字列となり
''
、パラメータ値は現在解析された値になります。
reviver 関数の 2 つの引数の key
合計 の場合value
、異なるデータ型は次のとおりです。
- 基本的な値タイプのデータ (文字列、数値、ブール値) と null、空のオブジェクト
{}
と空の配列[]
:
キーは空の文字列で、値は対応する解析された値です。
これはすでに最上位のレイヤーであり、他の属性を持っていないためです。 - オブジェクト object:
属性名と値に対応して、キーと値の両方が存在します。
最上位のレイヤーは、パラメーター キーが空の値を返します。 - 配列:
キーは配列のインデックスに対応し、値は要素の値に対応します。
最上位のレイヤーは、パラメーター キーが空の値を返します。
基本型の変換:
JSON.parse('5', function (key, value) {
console.log(`key:${key}, value:${value}`)
})
// key:, value:5
JSON.parse('null', function (key, value) {
console.log(`key:${key}, value:${value}`)
})
// key:, value:null
JSON.parse('{}', function (key, value) {
console.log(`key:${key}, value:`, value)
})
// key:, value:{}
オブジェクトのオブジェクトと配列:
JSON.parse('[1, 2]', function (key, value) {
console.log(`key:${key}, value:`, value)
})
// key:0, value: 1
// key:1, value: 2
// key:, value: (2) [empty × 2]
JSON.parse('{ "user": "张三", "info": { "age": 25, "sex": 1 } }', function (key, value) {
console.log(`key:${key}, value::`, value)
})
// key:user, value:: 张三
// key:age, value:: 25
// key:sex, value:: 1
// key:info, value:: {}
// key:, value:: {}
情報処理:
JSON.parse('[1, 2]', function (key, value) {
if(key === '') {
return value
}
return value + 3
})
// [4, 5]
JSON.parse 特性
JSON 文字列を解析するときは、JSON 形式のいくつかの仕様に注意する必要があります。そうしないと、エラーが報告されやすくなります。
JSON データには値の型と形式について厳密な規則があり、具体的な規則は次のとおりです。
- このメソッドでは文字列型のJSON形式のデータを使用します。
このメソッドは、数値、ブール値、null の 3 種類の値もサポートし、対応するリテラル値を変換します。
他のタイプはサポートされていません。
JSON.parse('"中国"')
// '中国'
JSON.parse(null) // null
JSON.parse(111.) // 111
JSON.parse(0x12) // 18
JSON.parse(true) // true
JSON.parse([])
// Uncaught SyntaxError: Unexpected end of JSON input
- 文字列には一重引用符ではなく二重引用符を使用する必要があります。
JSON.parse('"String"')
// 'String'
JSON.parse('\'String\'')
// Uncaught SyntaxError: Unexpected token ' in JSON at position 0
- 10 進数の文字列のみがサポートされますが、小数点の後に数値を続ける必要があります。
JSON.parse('111') // 111
JSON.parse('0x12')
// Uncaught SyntaxError: Unexpected token x in JSON at position 1
JSON.parse('111.232') // 111.232
JSON.parse('111.')
// Uncaught SyntaxError: Unexpected end of JSON input
- Unknown、Symbol、および BigInt は使用できません。また、数値は NaN、Infinity、および -Infinity をサポートしていないため、エラーが報告されます。
JSON.parse(undefined)
// Uncaught SyntaxError: Unexpected token u in JSON at position 0
JSON.parse(Symbol())
// Uncaught TypeError: Cannot convert a Symbol value to a string
JSON.parse('12n')
// Uncaught SyntaxError: Unexpected token n in JSON at position 2
[]
複合型は次 のようなリテラルのみです{}
。
オブジェクトコンストラクタはサポートされていない実行文とみなされるため、使用できません。
オブジェクトと配列、関数、RegExp オブジェクト、Date オブジェクト、Error オブジェクトなどは使用できません。
JSON.parse('[]')
// []
JSON.parse('Object()')
// Uncaught SyntaxError: Unexpected token O in JSON at position 0
- オブジェクトのプロパティ名には二重引用符を使用する必要があります。
JSON.parse('{"key": 1 }')
// {key: 1}
JSON.parse('{key: 1 }')
// Uncaught SyntaxError: Unexpected token k in JSON at position 1
- 配列またはオブジェクトの最後のメンバーの後にカンマを追加することはできません。
JSON.parse('[1, 2, 3, 4, ]')
// VM2771:1 Uncaught SyntaxError: Unexpected token ] in JSON at position 13
JSON.parse('{"key" : 1, }')
// VM2779:1 Uncaught SyntaxError: Unexpected token } in JSON at position 12
- Unicode エスケープのサポート。
JSON.parse('{"\u0066":333}')
// {f: 333}
- 「\n」、「\t」などの一部の制御文字とエスケープ文字はサポートされていません。
JSON.parse('"\n"')
// Uncaught SyntaxError: Unexpected token
他の解析方法
json 文字列を json オブジェクト (js オブジェクト値) に変換するには、他のメソッドを使用することもできますが、これは安全なコードではありません。
const str = '{"name":"json","age":18}'
const json = JSON.parse(str)
const json = eval("(" + str + ")")
const json = (new Function("return " + str))()
JSON.stringify
JSON.stringify()
JavaScript オブジェクトまたは値を JSON 形式の文字列に変換します。
JSON.stringify 構文
JSON.stringify(value[, replacer [, space]])
- value: JSON 文字列にシリアル化される JavaScript オブジェクトまたは値。
- replacer はオプションであり、シリアル化される値を処理するために使用されます。
- スペースはオプションで、出力を美しくするために使用されるインデント用の空白文字列を指定します。
戻り値: 指定された値を表す JSON 形式の文字列。
置換パラメータ
replacer パラメータは次の 3 つの状況で使用されます。
- null、未定義、またはその他の型の場合は無視され、処理されません。
JSON.stringify({key: 'json'}, null, null) // '{"key":"json"}'
JSON.stringify({key: 'json'}, true) // '{"key":"json"}'
- 配列の場合、配列に含まれるプロパティ名のみが結果文字列にシリアル化されます。これは
オブジェクト プロパティに対してのみ有効で、配列に対しては無効です。
const obj = {
json: 'JSON',
parse: 'PARSE',
stringify: 'STRINGIFY'
}
JSON.stringify(obj, ['parse', 'stringify'])
// '{"parse":"PARSE","stringify":"STRINGIFY"}'
- それが関数の場合、シリアル化された値の各属性は関数によって変換され、処理されます。
プロセス:
- この関数には、シリアル化される属性名 (キー) と属性値 (値) という 2 つのパラメーターがあります。
- 初めて呼び出すとき、キーは空の文字列で、値はシリアル化する必要があるオブジェクト全体です。
- 2 回目の処理では、最初の処理の結果が送信され、後続の各処理では前の処理の結果が受信されます。
- その後、各属性名と属性値が順番に処理され、完了後に返されます。
JSON.stringify({ json: 1, stringify: { val: 'rr'} }, (key, value) => {
console.log(`key:${key},value:`, value)
return value
})
// key:,value: {json: 1, stringify: {…}}
// key:json,value: 1
// key:stringify,value: {val: 'rr'}
// key:val,value: rr
// '{"json":1,"stringify":{"val":"rr"}}'
値型の処理:
- 基本タイプの文字列、数値、ブール値、null が返された場合は、シリアル化された JSON 文字列に直接追加されます。
- 他のオブジェクトが返された場合、そのオブジェクトのプロパティは順番にシリアル化され、それが関数の場合は処理されません。
- 返された場合、または未定義の場合、プロパティは出力されません。
- 配列をシリアル化するときに、値が未定義または関数を返した場合、null に置き換えられます。
JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
if (typeof value === 'number') {
return 'ss'
}
return value
})
// '{"json":"ss","stringify":"rr"}'
JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
if (typeof value === 'number') {
value = undefined
}
return value
})
// '{"stringify":"rr"}'
以下の例は、オブジェクトの値を返す場合の処理です。
JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
if (typeof value === 'object') { // 第一次返回整个对象时,类型是object
return { parse: 'dd' }
}
return value
})
'{"parse":"dd"}'
スペースパラメータ
space パラメーターは、結果文字列の間隔を制御し、出力を美しくするために使用されます。入力できる値は次の 3 種類です。
- 数値の場合、シリアル化するときに、各レベルは、前のレベルよりもその数値に対応するスペース (1 ~ 10 の範囲)、つまり最小 1 個、最大 10 個のスペースでインデントされます。
- それが文字列の場合、文字列はシリアル化中に各行の前に追加され、文字列は各レベルで前のレベルよりも 1 文字までインデントされ、それを超える場合は文字列がインターセプトされます。
- null、未定義、またはその他の型の場合は無視され、処理されません。
JSON.stringify({key: 'json'}, null, 2)
// '{\n "key": "json"\n}'
JSON.stringify({key: 'json', list: { str: 'str' } }, null, '|-')
// '{\n|-"key": "json",\n|-"list": {\n|-|-"str": "str"\n|-}\n}'
JSON.stringify({key: 'json'}, null, null)
// '{"key":"json"}'
JSON.stringify 特性
- 基本型の値の文字列、数値、ブール値、および文字列、ブール、数値オブジェクトの値は、出力用にプリミティブ値の文字列に変換されます。
JSON.stringify(333) // '333'
JSON.stringify(true) // 'true'
JSON.stringify(new String('333')) //'"333"'
JSON.stringify(Boolean(true)) // 'true'
- 文字列の基本型で、変換結果は二重引用符で囲まれます。
元に戻すときに、二重引用符によって JavaScript にそれが変数ではなく文字列であることが認識されるためです。
JSON.stringify('json') === 'json' // false
JSON.stringify('json') === '"json"' // true
- 未定義、関数、シンボル、および XML オブジェクト:
- Object オブジェクト内に出現しても無視されます。
- 配列に出現すると、null としてシリアル化されます。
- 単独で存在する場合は、未定義が返されます。
JSON.stringify(Symbol()) // undefined
JSON.stringify([Symbol(), Math.abs, undefined]) // '[null,null,null]'
JSON.stringify({ [Symbol()]: Math.abs, key: undefined }) // '{}'
- NaN、Infinity、-Infinity などの値、および null は null としてシリアル化されます。
JSON.stringify(null) // 'null'
JSON.stringify(NaN) // 'null'
- オブジェクト オブジェクトおよび
Map/Set/WeakMap/WeakSet
その他の複合タイプのオブジェクトは、シリアル化時にオブジェクトの走査不可能なプロパティを無視します。
const obj = {}
Object.defineProperties(obj, {
'json': { value: 'JSON', enumerable: true },
'stringify': { value: 'STRINGIFY', enumerable: false }
})
JSON.stringify(obj)
// '{"json":"JSON"}'
- 属性名として シンボル が含まれる属性は無視されます。
JSON.stringify({[Symbol()]: 333}) // '{}'
- 配列を除いて、他のオブジェクトのプロパティはシリアル化時に順序が崩れる可能性があります。
const a = { '1': 911, 'r': 822, '11': 9922}
JSON.stringify(a)
// '{"1":911,"11":9922,"r":822}'
- 変換されたオブジェクトが
toJSON()
メソッドを定義している場合、メソッドの戻り値は、変換されたオブジェクトのシリアル化された結果です。
プロセスは他の属性を無視します。
const a = { key: 'json' }
a.toJSON = () => 'JSON'
JSON.stringify(a)
// '"JSON"'
- RegExp オブジェクトと Error オブジェクトは両方とも、空のオブジェクト文字列としてシリアル化されます。
JSON.stringify(/\d/) // "{}"
JSON.stringify(new Error()) // "{}"
対応するオブジェクトをシリアル化するには、toJSON メソッドを実装する必要があります。
RegExp.prototype.toJSON = RegExp.prototype.toString
JSON.stringify(/\d/) // '"/\\\\d/"'
- Date オブジェクトは toJSON() を定義し、それを文字列 string に変換してシリアル化できるようにします。
同じですDate.toISOString()
。
JSON.stringify(new Date())
// '"2021-12-31T02:24:05.477Z"'
- 循環参照を持つオブジェクトがこのメソッドを実行すると、エラーがスローされます。
オブジェクトは相互に参照し、無限ループを形成します。
const a = {}
a.key = a
JSON.stringify(a)
// Uncaught TypeError: Converting circular structure to JSON
- BigInt 型の値を変換すると、TypeError エラーがスローされます。
BigInt 値は JSON シリアル化できません
JSON.stringify(12n)
// Uncaught TypeError: Do not know how to serialize a BigInt
- Unicode エスケープ文字のサポートの向上
const a = {'\u0066': 333}
JSON.stringify(a)
// '{"f":333}'