经常说(或问为什么)Google Closure Compiler (GCC) 用双引号替换单引号(即使compilation_level 设置为WHITESPACE_ONLY !!!):
示例 xmp_1.js:
alert('Hello world!'); // output: alert("Hello world!");
然而……这只是“真相”的一半,因为:
示例 xmp_2.js:
alert('Hello "world"!'); // output: alert('Hello "world"!');
// *NOT*: alert("Hello \"world\"!");
GCC 本质上是一个 'your raw javascript' 到 '更小(更高效)的 javascript' 的翻译器:所以它不会“盲目地”用双引号替换单引号引号,但尝试选择一个“最佳引号字符”(毕竟......主要目标之一是“缩小”脚本)。
从源代码 (CompilerOptions.java) 和 this issue-report 可以了解到:
如果字符串包含的单引号多于双引号,则
编译器将使用双引号包裹字符串,反之亦然。
如果字符串不包含引号或 相同数量的单个和
双引号,然后编译器将默认使用双引号。
像这个例子 xmp_3.js:
alert('Hello "w\'orld"!'); // output: alert('Hello "w\'orld"!');
alert('Hello "w\'o\'rld"!'); // alert("Hello \"w'o'rld\"!");
请注意上述 xmp_3 如何导致使用' 和" 作为外部引号的“混合”输出:最佳选择后跟默认值(当它无关紧要时)。
如何将默认双引号更改/覆盖为单引号?
事实证明,在现实世界中存在一些严重的合法案例,默认使用单引号会更好。正如上面引用的issue 836(从 2012 年 10 月 8 日起)中所述:
FT 网络应用程序 (app.ft.com) 和 Playbook 的 Economist 应用程序提供
JavaScript 与其他资源一起更新到客户端
将它们作为 JSON 编码对象的一部分进行传输。 JSON 使用双精度
原生引号,所以编译后的 JavaScript 中的所有双引号
需要转义。 这会使 FT 网络应用的 JS 的大小膨胀
传输大更新时大约 20kB。
问题的记者带来了一份礼物:一个补丁,添加了选项 prefer_single_quotes 以将默认引号字符从双引号更改为单引号。
这个问题被认真对待,以至于项目成员 Santos考虑将默认的双引号更改为单引号(“看看是否有人抱怨”).. TWICE(也在记者/补丁贡献者声明他将其作为一个选项实施之后,它不会产生任何向后兼容的后果,因为“有人可能会因为某些奇怪的原因而依赖用双引号输出的字符串”)。
但是,大约一周后补丁被接受 (r2258),又一周后重新设计 (r2257),2012 年 10 月 30 日,Santos 报告说现在可以通过以下方式启用该选项:
@987654334 @
(所以除了PRETTY_PRINT 和PRINT_INPUT_DELIMITER 之外的第三个选项用于formatting-key)。
(注意:在当前的源代码中,目前仍然可以找到大量对“prefer_single_quotes”的引用。)
用法:
如果您(下载并)使用(本地 java)应用程序:
java -jar compiler.jar --js xmp_1.js --formatting SINGLE_QUOTES
你会看到:alert('Hello world!'); 现在编译为alert('Hello world!');
但是,在撰写本文时,位于 http://closure-compiler.appspot.com 的编译器服务 API 和 UI(很可能使用该 API),不接受这第三个(新的,虽然一年存在)格式选项:SINGLE_QUOTES 并会抛出错误:
17: Unknown formatting option single_quotes.
在(再次)挖掘源代码之后,似乎(我不是 Java 专家)这是因为 jscomp/webservice/common/Protocol.java 只接受旧的 PRETTY_PRINT 和 PRINT_INPUT_DELIMITER
* All the possible values for the FORMATTING key.
*/
public static enum FormattingKey implements ProtocolEnum {
PRETTY_PRINT("pretty_print"),
PRINT_INPUT_DELIMITER("print_input_delimiter"),
;
如果此选项在 API 和/或 UI 中可用,我将更新此答案。
希望这有助于并节省一些时间,因为谷歌可以找到的关于SINGLE_QUOTES 的唯一文档和参考资料目前在这一期 836 和源代码中的一些 cmets 中。现在它对 SO 有一些解释(我期望它)。