Javascript 花括号对象表示法在任何表达式中有效吗?
我目前正在分析Javascript语言。看起来您可以将许多概念组合到一个名为expression的基本类型中。即使是函数参数和定义,以及字符串、数字和数学表达式,也适合该组。 唯一不合逻辑的例外是无意义上下文中的花括号对象表示法 由于函数由多个表达式组成,以下代码有效:Javascript 花括号对象表示法在任何表达式中有效吗?,javascript,expression,javascript-objects,curly-brackets,Javascript,Expression,Javascript Objects,Curly Brackets,我目前正在分析Javascript语言。看起来您可以将许多概念组合到一个名为expression的基本类型中。即使是函数参数和定义,以及字符串、数字和数学表达式,也适合该组。 唯一不合逻辑的例外是无意义上下文中的花括号对象表示法 由于函数由多个表达式组成,以下代码有效: function valid(){ /\W/; "ahll"; var alpha; alpha; alpha={"first": 90, "second": 80}; alpha
function valid(){
/\W/;
"ahll";
var alpha;
alpha;
alpha={"first": 90, "second": 80};
alpha;
0, {"first": 90, "second": 80};
[1,2,3];
alpha;
2+3;
new RegExp("/\W/");
return true;
}
出于意图,以下代码也应该有效,但第二行出现“missing;before statement”语法错误:
function invalid(){
{"first": 90, "second": 80};
return true;
}
在接受表达式的所有其他情况下都接受花括号对象表示法,但也允许使用花括号代码块的情况除外
上面提到的语法错误是由javascript的实现还是规范引起的
这种无意义的表达有更精确的名称吗?在上一个示例中,您所看到的对象实际上是: 从MDN: 块语句用于将零个或多个语句分组。块由一对花括号分隔 因此,基本上,当你开始大括号时,它理解为一个块,并给出错误:
Uncaught SyntaxError: Unexpected token :
因为它不喜欢块中的冒号(:
),它需要语句(var a=2
,等等)。它假定大括号后面的任何内容都必须是一组语句,因此看到冒号时会感到惊讶,并在混乱中抛出一个错误。请注意,“first”:90
不是有效的语句
那么为什么0,{“第一”:90,“第二”:80}代码>通过?
因为在看到第一个表达式(0
)和逗号运算符后,它希望看到类似类型的另一个值(即另一个表达式)。因此,它将第二个对象{“first”:90,“second”:80}
视为一个对象(也是一个表达式),而不是一个块
要进一步简化,请尝试{“first”:90,“second”:80},0
。请注意,它给出的语法错误与前一个完全相同。因为,一旦它看到{
,它就会将以下内容视为一个块,并再次抱怨冒号(:
)
如何避免这种情况?
将其作为另一个表达式的一部分,例如:
( {1:2} ) // a block doesn't come inside parentheses
var a = {1 : 2}; // a block can't be the RHS
myFunc( { 1 : 5 } ) // a block can't be a function argument
希望能有所帮助!这已在前面的问题中解决 大括号用于引入语句块或作为对象文字的开头。为了处理这种歧义,大括号在默认情况下被解释为语句块容器,因此示例中出现语法错误
当在运算符的RHS中使用大括号时,歧义消失;它是一个对象文字。解析器有优先权将
{
视为块的开始,而不是对象的开始
那么,在以下情况下,我们应该如何明确地告诉读者在乘法之前先进行加法:
3 * 4 + 2
也许这是:
3 * (4 + 2)
同样适用于
{"first": 90, "second": 80};
我们可以这样做
({"first": 90, "second": 80});
或者将其放在解析器理解您真正意图的其他各种方式中
上面提到的语法错误是由javascript的实现还是规范引起的
按规格
这种无意义的表达有更准确的名称吗
您正在寻找术语Expression Statement
。正如您所说,对象文字是表达式(偶数),就像大多数其他东西一样。它们可以出现在许多上下文中,如函数参数、运算符的操作数或括号内
然而,函数体——代码——并不是由表达式组成的,它是由表达式组成的。这意味着像if语句、循环语句或普通块。或者“表达式语句”,它们只不过是要计算的表达式(并且有副作用,它们大多不是“无意义的”)
然而:
表达陈述
:[前瞻∉ {{
,函数
}]表达式;
注意:表达式语句不能以开头卷曲开头
大括号,因为这可能会使其与。以及
ExpressionStatement不能以function关键字开头,因为
这可能会使函数声明变得模棱两可
在中定义了许多不同类型的表达式。开始问题中提到的“表达式”与主要表达式最匹配,如下所述:(每一条缩进的线都是可能的表示)
花括号代码块:
Block :
{ StatementList_opt } - A list of statements
在这种情况下最相关的声明:
ExpressionStatement :
[lookahead ∉ {{, function}] Expression ;
这只允许表达式开头不带开头的花括号或“function”-关键字。(FunctionDeclarations与语句和表达式分开,但作为FunctionExpression的lambda函数除外)
表达式定义不直接指定PrimaryExpression,但在一长串定义中,PrimaryExpression可以被视为表达式:
Expression:
AssignmentExpression
Expression, AssingmentExpression
我确实检查了整个定义链,以查看PrimaryExpression是否实际上是一个表达式。以下是定义链:
Expression:
AssignmentExpression:
ConditionalExpression:
LogicalORExpression:
LogicalANDExpression:
BitwiseORExpression:
BitwiseXORExpression:
BitwiseANDExpression:
EuqalityExpression:
RelationalExpression:
ShiftExpressions:
AdditiveExpression:
MultiplicativeExpression:
UnaryExpression:
PostfixExpression:
LeftHandSideExpression:
NewExpression:
MemberExpression:
PrimaryExpression:
回答问题
根据定义,中指定为ObjectLiteral的花括号对象表示法在每个表达式中都有效,但从语句派生的表达式除外,因为ExpressionStatement明确禁止将开头的花括号作为表达式的第一个字符出现,以解决与花括号的冲突ket代码块(定义为块)。FunctionBody、块、程序(全局范围)和所有循环构造(IterationStatements)都使用语句,因此在代码段中仅包含块而不包含ObjectLiteral
最后
规范限制花括号表示c或c
Expression:
AssignmentExpression:
ConditionalExpression:
LogicalORExpression:
LogicalANDExpression:
BitwiseORExpression:
BitwiseXORExpression:
BitwiseANDExpression:
EuqalityExpression:
RelationalExpression:
ShiftExpressions:
AdditiveExpression:
MultiplicativeExpression:
UnaryExpression:
PostfixExpression:
LeftHandSideExpression:
NewExpression:
MemberExpression:
PrimaryExpression: