JSON.rawJSON()

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

JSON.rawJSON() 静态方法创建一个包含一段 JSON 文本的“原始 JSON”对象。当序列化为 JSON 时,原始 JSON 对象会被视为已经是一段 JSON 文本。此文本必须是有效的 JSON。

语法

js
JSON.rawJSON(string)

参数

string

JSON 文本。必须是 **表示原始值** 的有效 JSON。

返回值

一个可用于创建与提供的 string 内容完全相同的 JSON 文本的对象,但字符串本身不带引号。此对象 具有 null 原型被冻结(因此它永远不会被任何类型的原始值转换意外地序列化为常规对象),并具有以下属性

rawJSON

提供的原始 JSON string

此外,它还有一个 私有字段,用于标记自身为原始 JSON 对象。这使得它能够被 JSON.stringify()JSON.isRawJSON() 识别。

异常

SyntaxError

如果 string 不是有效的 JSON,或者它表示一个对象或数组,则抛出异常。

描述

原始 JSON 对象可以被视为一种不可变的、原子化的数据结构,类似于任何一种 原始类型。它不是一个常规对象,除了原始 JSON 文本之外不包含任何数据。它用于将数据“预序列化”为 JSON.stringify 由于各种原因本身无法生成的格式。最常见的用例是浮点数精度丢失问题。例如:

js
JSON.stringify({ value: 12345678901234567890 });
// {"value":12345678901234567000}

该值不再与原始数字完全等效!这是因为 JavaScript 对所有数字都使用浮点表示,因此无法精确表示所有整数。数字字面量 12345678901234567890 在被 JavaScript 解析时,本身已经被舍入到最接近的可表示数字。

没有 JSON.rawJSON,无法告诉 JSON.stringify 生成数字字面量 12345678901234567890,因为根本不存在相应的 JavaScript 数字值。通过原始 JSON,您可以直接告诉 JSON.stringify() 特定值应该如何字符串化:

js
const rawJSON = JSON.rawJSON("12345678901234567890");
JSON.stringify({ value: rawJSON });
// {"value":12345678901234567890}

有关此内容的更完整示例,请参阅 无损数字序列化

请注意,尽管我们将字符串传递给了 JSON.rawJSON(),但在最终的 JSON 中它仍然是一个数字。这是因为字符串表示的是原始的 JSON 文本。如果您想序列化一个字符串,您应该使用 JSON.rawJSON() 并提供一个用引号括起来的字符串值:

js
const rawJSON = JSON.rawJSON('"Hello world"');
JSON.stringify({ value: rawJSON });
// {"value":"Hello world"}

JSON.rawJSON 允许您插入任意 JSON 文本,但不允许您创建无效的 JSON。对于 JSON 语法不允许的任何内容,JSON.rawJSON() 也不允许。

js
const rawJSON = JSON.rawJSON('"Hello\nworld"'); // Syntax error, because line breaks are not allowed in JSON strings

此外,您不能使用 JSON.rawJSON() 来创建 JSON 对象或数组。

示例

使用 JSON.rawJSON() 创建不同类型的 JSON 表达式

js
const numJSON = JSON.rawJSON("123");
const strJSON = JSON.rawJSON('"Hello world"');
const boolJSON = JSON.rawJSON("true");
const nullJSON = JSON.rawJSON("null");

console.log(
  JSON.stringify({
    age: numJSON,
    message: strJSON,
    isActive: boolJSON,
    nothing: nullJSON,
  }),
);

// {"age":123,"message":"Hello world","isActive":true,"nothing":null}

然而,您不能使用 JSON.rawJSON() 来创建 JSON 对象或数组。

js
const arrJSON = JSON.rawJSON("[1, 2, 3]");
const objJSON = JSON.rawJSON('{"a": 1, "b": 2}');
// SyntaxError

使用 JSON.rawJSON() 创建转义的字符串字面量

除了数字,JavaScript 值和 JSON 文本之间只有一个其他类型没有一对一的对应关系:字符串。当字符串序列化为 JSON 时,除了在 JSON 字符串字面量中非法(例如换行符)的所有代码点外,都会被原样打印。

js
console.log(JSON.stringify({ value: "\ud83d\ude04" })); // {"value":"😄"}

这可能不是期望的行为,因为接收此字符串的一方可能以不同的方式处理 Unicode。为了提高互操作性,您可以显式指定要用转义序列序列化的字符串:

js
const rawJSON = JSON.rawJSON('"\\ud83d\\ude04"');
const objStr = JSON.stringify({ value: rawJSON });
console.log(objStr); // {"value":"\ud83d\ude04"}
console.log(JSON.parse(objStr).value); // 😄

请注意,rawJSON 中的双反斜杠实际上表示单个斜杠字符。

规范

规范
JSON.parse 源文本访问
# sec-json.rawjson

浏览器兼容性

另见