为什么 JSON 是 JavaScript 的子集?

Why JSON is a subset of JavaScript?

Wikipedia says 即 JSON 被设计为 JavaScript 的非严格子集,即允许使用一些 Unicode 字符。引用截至 2015-11-05 的当前版本:

Though JSON is commonly perceived as being a subset of JavaScript and ECMAScript, it allows some unescaped characters in strings that are illegal in JavaScript and ECMAScript strings.

但是.. 如果我在 ESLint 中粘贴 Wikipedia 页面中的任何示例,它会失败并出现错误。

例如我粘贴这个:

{
  "id": 1,
  "name": "Foo"
}

进入http://eslint.org/demo/得到:

2:8 - Parsing error: Unexpected token : (undefined)

出于某种原因,冒号在 JavaScript 中似乎是非法的,这与字符串中的未转义字符无关。

为什么人们仍然称 JSON 为 JavaScript 子集?

JSON 是一个子集,因为它仅用于数据。 JavaScript 允许定义函数和执行语句。 JSON 只允许定义数据。这就是为什么它是一个子集。

您在尝试将 JSON 验证为 JavaScript 语句 时收到的错误是您的数据不是 语句。转换成语句,在eslint上看不到错误:

var foo = {
    "id": 1,
    "name": "Foo"
    };

您 运行 遇到了一个有点常见的问题:松散的对象文字被解释为块,而不是对象。

如果在开头添加var foo =,则完全有效:

var foo = {
  "id": 1,
  "name": "Foo"
}

如果没有 var foo 来声明和初始化变量,解析器会看到一个块(如 if (true) { ... })和字符串文字 ("id")。松散字符串文字后的冒号是不合法的,因为那在任何地方都不是真正的 JS:

"id": foo(); // doesn't make sense

这更常见于对象文字中未加引号的属性,解析器将其解释为命名标签(很少使用的 foo: 用于 goto 的语法)。构造

{
  id: 1,
  name: "Foo"
}

看起来像一个带有标签 id(指向表达式 1)、逗号运算符和另一个标签的块。同样,这没有多大意义,但第一部分至少是合法的解析。

因为您遵循的是 JSON 规范而不是 JS 对象字面量并引用了您的 属性 名称,所以它会将它们作为字符串字面量提取,并且无法从那里弄清楚该怎么做.

有趣的是,如果你要使用:

{
  "id".toString(),
  "name".substr(1)
}

那么 ESlint 就不会抱怨了。它很奇怪而且不是很有用,但却是一个完全合法的语言结构。

JSON 是 JavaScript object 符号的子集。你不能凭空声明一个对象。

该对象的 JavaScript 用法是将其分配给一个变量:

var o = {
  "id": 1,
  "name": "Foo"
};

或将其传递给函数:

console.dir( {"id": 1, "name": "Foo" } );

等等

问题是解析器还不能确定它是对象上下文。您可以将其包装在 ():

({
    "id": 1,
    "name": "Foo"
})

它会如您所愿。