在JavaScript AST中遇到EmptyStatement的所有方法是什么



我正在写一个JS transpiler,需要知道我会遇到什么。除了晦涩难懂的EmptyStatement,我几乎处理过每一个边缘案例。我遇到的一个地方是这里:

for (arrL = arr.length; arrL--; arr[arrL] *= baseIn);

AST看起来像这样:

{
"type": "Program",
"body": [
{
"type": "BlockStatement",
"body": [
{
"type": "AssignmentExpression",
"left": {
"type": "Identifier",
"start": 4014,
"end": 4018,
"name": "arrL"
},
"right": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"start": 4021,
"end": 4024,
"name": "arr"
},
"property": {
"type": "Identifier",
"start": 4025,
"end": 4031,
"name": "length"
},
"computed": false
},
"operator": "="
},
{
"type": "WhileStatement",
"test": {
"type": "Literal",
"value": true,
"raw": "true"
},
"body": {
"type": "BlockStatement",
"body": [
{
"type": "IfStatement",
"test": {
"type": "UpdateExpression",
"argument": {
"type": "Identifier",
"start": 4033,
"end": 4037,
"name": "arrL"
},
"operator": "--",
"prefix": false
},
"consequent": {
"type": "BlockStatement",
"body": [
{
"type": "EmptyStatement",
"start": 4061,
"end": 4062
},
{
"type": "AssignmentExpression",
"left": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"start": 4041,
"end": 4044,
"name": "arr"
},
"property": {
"type": "Identifier",
"start": 4045,
"end": 4049,
"name": "arrL"
},
"computed": true
},
"right": {
"type": "Identifier",
"start": 4054,
"end": 4060,
"name": "baseIn"
},
"operator": "*="
}
]
},
"alternate": {
"type": "BlockStatement",
"body": [
{
"type": "BreakStatement"
}
]
}
}
]
}
}
]
}
]
}

我甚至不知道EmptyStatement指的是什么,哈哈。遇到EmptyStatement的其他情况是什么?

如果仔细观察for语句,您会发现它的主体仅由;组成。这是一句空话。你会得到同样的效果,比如说

if (a--);

尽管许多风格指南不鼓励这样做。{}要清晰得多,imho。这是一个空块,而不是一个空语句。{;}将是一个仅由一个空语句组成的块,这也是非常罕见的,但您可能会发现类似于:

if (debugging) {
/* Commented out for now */ ;
}

那么,什么是空洞的陈述?这是一个只有分号终止符的语句。正如它所说的,空的。

有趣的是,for语句已经被取消了,这可能会让人感到困惑。但这是正确的;for(init; test; advance) body;在语义上等同于

{
init;
while(true) {
if (test) {
body;
advance;
}
else 
break;
}
}

显然,尽管它淡化了for语句,但它保留了空体。这可能是为了有一个挂行号的地方,也可能只是为了在解析时更容易将其留在那个位置。将(隐含的(while (test) { ... }转换为while (true) { if (test) { ... } else break; }可能是为了简化基本块的分解,或者实现对代码进行重新排序的标准优化。不过只是猜测而已。

相关内容

最新更新