JSON.parse()
Baseline 廣泛可用 *
JSON.parse() 靜態方法解析 JSON 字串,構建該字串所描述的 JavaScript 值或物件。可以選擇提供一個可選的 reviver 函式,在返回結果物件之前對其進行轉換。
試一試
const json = '{"result":true, "count":42}';
const obj = JSON.parse(json);
console.log(obj.count);
// Expected output: 42
console.log(obj.result);
// Expected output: true
語法
JSON.parse(text)
JSON.parse(text, reviver)
引數
文字-
要解析為 JSON 的字串。有關 JSON 語法的描述,請參閱
JSON物件。 reviver可選-
如果是一個函式,它規定了從解析中原始生成的值在返回前如何進行轉換。不可呼叫的值將被忽略。該函式使用以下引數呼叫:
key-
與值關聯的鍵。
value-
透過解析產生的值。
context可選-
一個上下文物件,其中包含與當前正在恢復的表示式相關的狀態。每次呼叫 reviver 函式時,它都是一個新物件。僅在恢復原始值時傳遞,當
value是物件或陣列時則不傳遞。它包含以下屬性:source-
表示此值的原始 JSON 字串。
返回值
異常
SyntaxError-
如果要解析的字串不是有效的 JSON,則丟擲此錯誤。
描述
JSON.parse() 按照 JSON 語法 解析 JSON 字串,然後像 JavaScript 表示式一樣計算該字串。JSON 文字表示的值與相同的 JavaScript 表示式表示的值不同的唯一情況是處理 "__proto__" 鍵時 — 請參閱 物件字面量語法與 JSON。
reviver 引數
如果指定了 reviver,則在返回解析計算出的值之前對其進行轉換。具體來說,計算出的值及其所有屬性(以 深度優先 方式,從最巢狀的屬性開始,然後處理到原始值本身)將單獨透過 reviver 進行處理。
reviver 使用包含正在處理的屬性的物件作為 this 呼叫(除非您將 reviver 定義為箭頭函式,在這種情況下沒有單獨的 this 繫結),並帶有兩個引數:key 和 value,分別代表屬性名(字串,即使是陣列)和屬性值。對於原始值,還會傳遞一個額外的 context 引數,其中包含此值的源文字。如果 reviver 函式返回 undefined(或不返回任何值 — 例如,如果執行結束於函式末尾),則該屬性將從物件中刪除。否則,該屬性將被重新定義為返回值。如果 reviver 只轉換某些值而不轉換其他值,請務必將所有未轉換的值原樣返回 — 否則,它們將從結果物件中刪除。
與 JSON.stringify() 的 replacer 引數類似,對於陣列和物件,reviver 最後一次被呼叫是在根值上,key 為空字串,value 為根物件。對於其他有效的 JSON 值,reviver 的工作方式類似,並被呼叫一次,key 為空字串,value 為值本身。
如果您從 reviver 返回另一個值,該值將完全替換原始解析的值。這甚至適用於根值。例如:
const transformedObj = JSON.parse('[1,5,{"s":1}]', (key, value) =>
typeof value === "object" ? undefined : value,
);
console.log(transformedObj); // undefined
沒有通用的方法可以解決這個問題。您無法專門處理 key 是空字串的情況,因為 JSON 物件也可以包含空字串作為鍵。實現 reviver 時,您需要非常精確地知道每個鍵需要哪種轉換。
請注意,reviver 在值解析之後執行。因此,例如,JSON 文字中的數字將已經轉換為 JavaScript 數字,並且在此過程中可能會丟失精度。一種在不丟失精度的情況下處理大數字的方法是將它們序列化為字串,然後將它們恢復為 BigInts 或其他合適的任意精度格式。
您還可以使用 context.source 屬性來訪問表示該值的原始 JSON 源文字,如下所示:
const bigJSON = '{"gross_gdp": 12345678901234567890}';
const bigObj = JSON.parse(bigJSON, (key, value, context) => {
if (key === "gross_gdp") {
// Ignore the value because it has already lost precision
return BigInt(context.source);
}
return value;
});
示例
使用 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 引數
JSON.parse(
'{"p": 5}',
(key, value) =>
typeof value === "number"
? value * 2 // return value * 2 for numbers
: value, // return everything else unchanged
);
// { 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
// ""
在與 JSON.stringify() 的 replacer 配對時使用 reviver
為了使一個值能夠正確地進行往返(即,它被反序列化為與原始物件相同的物件),序列化過程必須保留型別資訊。例如,您可以使用 JSON.stringify() 的 replacer 引數來實現此目的:
// Maps are normally serialized as objects with no properties.
// We can use the replacer to specify the entries to be serialized.
const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"],
]);
const jsonText = JSON.stringify(map, (key, value) =>
value instanceof Map ? Array.from(value.entries()) : value,
);
console.log(jsonText);
// [[1,"one"],[2,"two"],[3,"three"]]
const map2 = JSON.parse(jsonText, (key, value) =>
Array.isArray(value) && value.every(Array.isArray) ? new Map(value) : value,
);
console.log(map2);
// Map { 1 => "one", 2 => "two", 3 => "three" }
因為 JSON 沒有用於註解型別元資料的語法空間,為了恢復非純物件的 JSON 值,您必須考慮以下幾種方法之一:
- 將整個物件序列化為字串,並在前面加上型別標籤。
- 根據資料的結構進行“猜測”(例如,一個包含兩個成員陣列的陣列)
- 如果有效載荷的形狀是固定的,則根據屬性名進行(例如,所有名為
registry的屬性都包含Map物件)。
無效 JSON
當 JSON.parse 收到不符合 JSON 語法的字串時,它會丟擲 SyntaxError。
JSON 中的陣列和物件不能有尾部逗號
JSON.parse("[1, 2, 3, 4, ]");
// SyntaxError: Unexpected token ] in JSON at position 13
JSON.parse('{"foo": 1, }');
// SyntaxError: Unexpected token } in JSON at position 12
JSON 字串必須用雙引號(而不是單引號)分隔
JSON.parse("{'foo': 1}");
// SyntaxError: Unexpected token ' in JSON at position 1
JSON.parse("'string'");
// SyntaxError: Unexpected token ' in JSON at position 0
如果您在 JavaScript 字串字面量中編寫 JSON,您應該使用單引號分隔 JavaScript 字串字面量,或者轉義分隔 JSON 字串的雙引號。
JSON.parse('{"foo": 1}'); // OK
JSON.parse("{\"foo\": 1}"); // OK
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-json.parse |
瀏覽器相容性
載入中…