javascript - Google Closure Compiler 如何处理引号(字符串文字)?

标签 javascript quotes google-closure-compiler

问题“Google Closure Compiler 如何处理引号(字符串文字)?”也可以重新表述为:

  • 为什么 Closure 用双引号替换/交换单引号?
  • Closure 如何决定使用哪种引用格式/样式?
  • (如何)更改此(默认)行为?

注1:这个问题不是关于为什么闭包(或其他一些缩小器)选择更喜欢双引号(如所问的 herehere )。

注2:这个问题不是关于单引号和双引号的讨论,但是了解 GCC 对我们的代码做了什么(以及为什么)是相当有用的!

最佳答案

人们经常说(或问为什么)Google Closure C编译器(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 本质上是一个“你的原始 javascript”“更小(更高效)的 javascript” 翻译器:因此它不会“盲目地”用双引号替换单引号引号,但尝试选择“最佳引号字符”(毕竟......主要目标之一是“迷你化”脚本)。

来自源代码 ( CompilerOptions.java ) 和 this issue-report人们可以了解到:

If the string contains more single quotes than double quotes then the compiler will wrap the string using double quotes and vice versa.
If the string contains no quotes or an equal number of single and double quotes, then the compiler will default to using double quotes.

就像这个示例 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 日起)上述引用:

The FT web app (app.ft.com) and the Economist app for Playbook deliver JavaScript updates to the client along with other resources by transmitting them as part of a JSON-encoded object. JSON uses double quotes natively, so all the double quotes in the compiled JavaScript need to be escaped. This inflates the size of the FT web app's JS by about 20kB when transmitting a large update.

该问题的报告者带来了一份礼物:添加了选项 prefer_single_quotes 的补丁,用于将默认引号字符从双引号更改为单引号。

这个问题得到了足够的重视,项目成员桑托斯考虑将默认的双引号更改为单引号(“看看是否有人提示”)..两次(也在记者/补丁贡献者表示他将其作为一个选项实现之后,这样就不会产生任何向后兼容性的后果,因为“有人可能会出于某种奇怪的原因依赖双引号输出的字符串”)。

但是,大约一周后,该补丁被接受(r2258),又一周后进行了返工(r2257),2012 年 10 月 30 日,Santos 报告说现在可以通过以下方式启用该选项:
--formatting=SINGLE_QUOTES
(因此除了 PRETTY_PRINTPRINT_INPUT_DELIMITER 之外,还有用于 formatting 键的第三个选项)。
(注意:在当前的源代码中,目前仍然可以找到大量对“prefer_single_quotes”的引用。)

用法:
如果您(下载并)使用(本地 java)应用程序:

java -jar compiler.jar --js xmp_1.js --formatting SINGLE_QUOTES 您将看到: alert('Hello world!'); 现在编译为 alert('Hello world!');

但是,在撰写本文时,编译器服务 API 和 UI(最有可能使用该 API)位于 http://closure-compiler.appspot.com ,不要接受第三个(新的,虽然已经存在一年)格式化选项:SINGLE_QUOTES,并且会抛出错误:
17:未知的格式选项 single_quotes。

(再次)挖掘源代码后,似乎(我不是 Java 专家)这是因为 jscomp/webservice/common/Protocol.java仅接受旧版 PRETTY_PRINTPRINT_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 中提供此选项,我将更新此答案。

希望这可以帮助并节省一些时间,因为 google 可以找到的有关 SINGLE_QUOTES 的唯一文档和引用资料目前位于第 836 期以及源代码中的一些注释中。现在它对 SO 有一些解释(我期望的)。

关于javascript - Google Closure Compiler 如何处理引号(字符串文字)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19874862/

相关文章:

javascript - 将 DIV 拖动到水平可排序容器

r - 在 R 中嵌套两种以上的引号

python - 用单引号或双引号在 Python 中提取字符串

javascript - javascript 中 "this."的不当使用

javascript - 如何重命名/保留回调方法

javascript - 在客户端调整/裁剪图像大小的最佳方法是什么?

javascript - IE7/8 + <time> 标签 + jQuery .clone() =?

javascript - 是否可以检查 javascript (rails) 中是否存在 Flash 消息

JavaScript HERE-doc 或其他大引用机制?

Javascript Closure 编译器——导出全局变量