image.png

下面这段简单的 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;
}

如何修复

有两种常见做法都能解决这个问题:

  1. 让对象字面量跟在 return 同一行

    function getResult(a, b) {
        return {
            result: a + b
        };
    }
  2. 在对象外包一层小括号

    function getResult(a, b) {
        return (
            {
                result: a + b
            }
        );
    }

两种写法都能保证没有意外的分号插入,从而让函数正常返回 { result: 5 }


小结

这个 Bug 并不常见,但偶尔会让人头疼半天。如果在代码中习惯把大括号换行到下一行,又忘了手动加分号,就可能被 ASI“坑”到。
平时可以多注意一下这个特性,或者手动在 return 后面写对象时直接跟在同一行,避免自动分号的意外影响。自动格式化工具有时也会发生这种失误,看到这里或许就知道要警惕什么了。

首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。


王大冶
68.1k 声望105k 粉丝