【问题标题】:Disable, or at least detect, automatic semicolon insertion禁用或至少检测自动分号插入
【发布时间】:2013-08-28 07:50:02
【问题描述】:

我总是在strict mode 中编码,希望能够避免(或至少强制要求更改我的代码)免受 Javascript 语言问题的影响,例如使用过时的方法或错误解释的语法。

但是我今天遇到了this 问题,我想知道是否有任何方法可以禁用浏览器中的分号插入或其他类似严格模式的“编译”时错误?

JS[H/L]int 碰巧无法识别 JS 解释器在哪里插入分号并标记它们以供我们缓解吗?


编辑

JShintJSLint 如果在 return 关键字之后找到分号之前存在新行,则会出错。但是,我不知道有关自动插入的其他注意事项以及它们是否也被检测到。
无论如何,如果答案确实解决了“禁用”部分,那将更相关。

【问题讨论】:

标签: javascript syntax


【解决方案1】:

return 关键字之后的表达式必须始终与关键字在同一行开始,这与解释器无关,它是由 ECMAScript 标准定义的,这是语言的一个坏部分,但如果你尊重写作规则Douglas Crockford 描述的 JS 代码,你就不会再遇到这种情况了。

来自 Douglas Crockford 的“JavaScript: The Good Parts”(附录 A.3 糟糕的部分):

JavaScript 有一种通过自动插入分号来尝试纠正错误程序的机制。不要依赖于此。它可以掩盖更严重的错误。

它有时会在不欢迎分号的地方插入分号。考虑在 return 语句中插入分号的后果。如果 return 语句返回一个值,则该值表达式必须与 return 在同一行开始:

return
{
    status: true
};

这似乎返回了一个包含状态成员的对象。不幸的是,分号插入会将其变成返回未定义的语句。没有警告分号插入导致对程序的误解。如果将 { 放在上一行的末尾而不是下一行的开头,则可以避免该问题:

return {
    status: true
};

另请参阅 Douglas Crockford 的 JavaScript 代码约定:http://javascript.crockford.com/code.html

【讨论】:

  • 虽然这是真的,但我不怀疑还有其他警告。无论如何,至少看看 JS 解释器在我们的代码中插入内容的位置可能会很有趣(如果有一个自动化的解决方案。而不是学习它的具体情况)
  • @Hashbrown,请查看我编辑的答案,我不知道任何自动化解决方案,但如果您使用类似 Java 的代码样式,这个问题就解决了。
  • 我知道发生了什么,我想阻止它。我不是“依赖”插入,它阻碍了我。再说一次,问题的重点与return 问题无关,这只是引起了我的注意,它还会插入其他我想要根除的东西
  • 看起来禁用可能要求太多,但我很乐意简单地检测插入,即从编译器那里得到一份报告,告诉我它做了什么。我太愚蠢了,无法编写始终遵循 ECMAScript 标准或 Crockford 的代码——我什至知道拼写错误和语法很差,有时在同一天。对于那种愚蠢,我需要一个自动化的过程,而不是另一个人告诉我要塑造。
  • 这不是问题的真正答案,只是“你做错了”,没有帮助
【解决方案2】:

只是想我会帮助遇到这个问题的人。
我已经开始使用 Google 的 Closure Comiler 来缩小项目的 JS,它给了我一些方便的警告。

   $> java -jar google_closure_compiler.jar  --language_in=ECMASCRIPT5_STRICT --js_output_file 'min.js' 'file1.js' 'file2.js'
   file1.js:152: WARNING - unreachable code
               getSomething(function() { return this.doThingo(''); });
               ^

   file2.js:203: WARNING - Suspicious code. The result of the 'add' operator is not being used.
               ' to ' + (typeof obj);
               ^

   0 error(s), 2 warning(s)

有问题的代码块如下(cmets 描述了编译器提醒我注意的代码丢失了什么):

file1.js:150

    return generateSomeObject(bunch, of, arguments)
        //the period before the function call was missing
        getSomething(function() { return this.doThingo(''); });
}

file2.js:201

if (someCondition)
    //trailing plus was missing from this line
    throw 'Could not set ' + last + ' of ' + (typeof root)
        ' to ' + (typeof obj);
return old;

我不知道它是否会识别浏览器整理的所有错误(所以我可能不会将此标记为答案),但它比 YUI 的缩小器所做的要多得多为我做事(忽略了所有这些情况)。
此外,与 YUI 相比,编译器能够接受多个文件输入,因此可以为我提供每个文件的行号以查找错误,并且不会t 错误/重做 debugger 关键字)。
希望对你也有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 2015-04-08
    • 2019-05-02
    相关资源
    最近更新 更多