--- title: JSON.parse() slug: Web/JavaScript/Reference/Global_Objects/JSON/parse tags: - ECMAScript 5 - JSON - JavaScript - Method - Reference - メソッド translation_of: Web/JavaScript/Reference/Global_Objects/JSON/parse ---
JSON.parse() メソッドは文字列を JSON として解析し、文字列によって記述されている JavaScript の値やオブジェクトを構築します。任意の reviver 関数で、生成されたオブジェクトが返される前に変換を実行することができます。
JSON.parse(text[, reviver])
textreviver {{optional_inline}}{{jsxref("Object")}}, {{jsxref("Array")}}, 文字列, 数値, 論理値, null 値のいずれかで、指定された JSON の text に対応する値です。
解析する文字列が有効な JSON でない場合、{{jsxref("SyntaxError")}} 例外が発生します。
// From https://github.com/douglascrockford/JSON-js/blob/master/json2.js
if (typeof JSON.parse !== "function") {
var rx_one = /^[\],:{}\s]*$/;
var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
JSON.parse = function(text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k;
var v;
var value = holder[key];
if (value && typeof value === "object") {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
rx_dangerous.lastIndex = 0;
if (rx_dangerous.test(text)) {
text = text.replace(rx_dangerous, function(a) {
return (
"\\u" +
("0000" + a.charCodeAt(0).toString(16)).slice(-4)
);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with "()" and "new"
// because they can cause invocation, and "=" because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
// replace all simple value tokens with "]" characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or "]" or
// "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
if (
rx_one.test(
text
.replace(rx_two, "@")
.replace(rx_three, "]")
.replace(rx_four, "")
)
) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The "{" operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval("(" + text + ")");
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return (typeof reviver === "function") ?
walk({
"": j
}, "") :
j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError("JSON.parse");
};
}
JSON.parse('{}'); // {}
JSON.parse('true'); // true
JSON.parse('"foo"'); // "foo"
JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
JSON.parse('null'); // null
reviver が指定された場合、解析によって計算された値は、オブジェクトを返す前に変換されます。正確に言えば、計算された値とそのすべてのプロパティ(最もネストされたプロパティから始まり、元の値へと進みます)はそれぞれ reviver を通して変換されます。reviver は処理されるプロパティを含むオブジェクトが this として、また文字列のプロパティ名とプロパティの値を引数として呼び出されます。もし reviver 関数が {{jsxref("undefined")}} を返したり、何の値も返さなかったり(例えば実行が関数の終わりで{{訳注('return 文によってではなくて')}}終了した場合)した場合、そのプロパティはオブジェクトから削除されます。そうでなければそのプロパティはその戻り値として再定義されます。
もし reviver が一部の値だけを変換して他を変換しないのであれば、必ずすべての変換されない値をそのまま返すようにします。そうしなければ、それらの値は結果のオブジェクトから削除されるでしょう。
JSON.parse('{"p": 5}', (key, value) =>
typeof value === 'number'
? value * 2 // 数値ならば値の2倍を返す
: value // それ以外ならば変更しない
);
// { p: 10 }
JSON.parse('{"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}}', (key, value) => {
console.log(key); // 現在のプロパティ名を出力する。最後は ""。
return value; // 変更されていないプロパティの値を返す。
});
// 1
// 2
// 4
// 6
// 5
// 3
// ""
// 両方とも SyntaxError をスローする
JSON.parse('[1, 2, 3, 4, ]');
JSON.parse('{"foo" : 1, }');
// SyntaxError が発生
JSON.parse("{'foo': 1}");
| 仕様書 |
|---|
| {{SpecName('ESDraft', '#sec-json.parse', 'JSON.parse')}} |
{{Compat("javascript.builtins.JSON.parse")}}