为什么 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"
}
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"
})
它会如您所愿。
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"
}
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"
})
它会如您所愿。