1

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

尽管 JSON 通常被认为是 JavaScript 和 ECMAScript 的子集,但它允许在 JavaScript 和 ECMAScript 字符串中非法的字符串中包含一些未转义的字符。

但是..如果我将任何来自 Wikipedia 页面的示例粘贴到 ESLint 中,它会因错误而失败。

例如我粘贴这个:

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

进入http://eslint.org/demo/并获取:

2:8 - 解析错误:意外令牌:(未定义)

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

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

4

4 回答 4

7

JSON 是 JavaScript对象表示法的一个子集。您不能凭空声明一个对象。

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

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

或将其传递给函数:

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

等等

于 2015-11-04T19:51:13.867 回答
3

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

如果你添加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 不会抱怨。这很奇怪,也不是很有用,但却是一种完全合法的语言结构。

于 2015-11-04T19:51:04.770 回答
2

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

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

它会做你所期望的。

于 2015-11-04T19:51:39.080 回答
1

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

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

var foo = {
    "id": 1,
    "name": "Foo"
    };
于 2015-11-04T19:50:58.860 回答