下面这段简单的 JavaScript 代码里藏着一个不起眼但足以让人抓狂的错误:
function getResult(a, b) {
return
{
result: a + b
};
}
console.log(getResult(2, 3)); // 结果真的是 5 吗?
表面看上去,这只是一个“把两个数相加,然后返回对象”的函数,可实际运行后却并非预期的 { result: 5 }
。乍一眼看不出任何毛病,但结果可能会让你大吃一惊。
Bug 原因
实际输出会是 undefined。为什么?这是 JavaScript 的自动分号插入(Automatic Semicolon Insertion, ASI)在作祟:
- return 语句后面由于换行,JavaScript 会在此自动插入一个分号。
- 花括号 {} 便被解释成代码块而不是对象字面量。
- 这样一来,真正的返回语句被看作 return;,函数自然就返回了 undefined。
用“JS 眼中的解释”来写就是:
return; // 这行被自动插入了分号
{
result: a + b;
}
如何修复
有两种常见做法都能解决这个问题:
让对象字面量跟在 return 同一行:
function getResult(a, b) {
return {
result: a + b
};
}
在对象外包一层小括号:
function getResult(a, b) {
return (
{
result: a + b
}
);
}
两种写法都能保证没有意外的分号插入,从而让函数正常返回 { result: 5 }
。
小结
这个 Bug 并不常见,但偶尔会让人头疼半天。如果在代码中习惯把大括号换行到下一行,又忘了手动加分号,就可能被 ASI“坑”到。
平时可以多注意一下这个特性,或者手动在 return
后面写对象时直接跟在同一行,避免自动分号的意外影响。自动格式化工具有时也会发生这种失误,看到这里或许就知道要警惕什么了。