为什么Google Closure Compiler使用null==a而不是a==null进行优化?

3
所以在生产之前,我使用Google Closure Compiler来缩小我的JavaScript。今天,我注意到它是如何缩小和优化代码的,并意识到以下趋势:
编译以下代码:
function b(a) {
    if ( a == null ) {
       console.log('ohai');
    }
}

导致比较表达式的优化,其中字面量移到左边,变量移到右边。就像这样:

function b(a){null==a&&console.log("ohai")}

(顺便说一下,它会用单引号代替双引号。) 如果另一个操作数是对象,则表达式保持不变。为什么将文字字面量移动到运算符左侧可以优化表达式呢?


我的猜想是,这不是性能优化,而是可读性优化。将 null 放在前面意味着即使在非常长的条件语句中,也很清楚它是对 null 进行测试(这是一种常见模式)。任何明智的 == 定义(我在看你,PHP)都应该是可交换的(x == y <=> y == x)。 - Two-Bit Alchemist
6
保持一致的参数顺序会创建更长的公共字符串,这样可以更好地进行gzip压缩。为什么Google Closure会交换参数顺序? - DCoder
@Two-BitAlchemist 这里不会讨论可读性,因为闭包编译器也在缩小代码,从而删除任何不必要的空格,将变量重命名为尽可能短的名称等。它极大地降低了可读性。例如,看看minified JQuery。不确定是否使用了Google的工具进行缩小,但思路是相同的。 - Daniël Knippers
就像我说的那样,那只是一个猜测。我认为@DCoder可能是对的。我假设无论你是否打开了“缩小”选项,它都可能存在,你知道吗? :P - Two-Bit Alchemist
1个回答

0

没有优化改进(编辑:可能是一个草率的陈述,DCoder的评论例如是有效的),但你可以为此辩论它只是谨慎的做法

例如,程序员可能会不小心使用单个=而不是==——导致赋值而不是相等检查。

以下代码将默默地评估而不会出错:

var a = null;
function b(a){a=null&&console.log("ohai")} // notice the single =
b(a); // nothing

然而,Google 的方法会在控制台中产生一个错误(在 Chrome 中测试过)。
var a = null;
function b(a){null=a&&console.log("ohai")} // notice the single =
b(a); // produces error Uncaught ReferenceError: Invalid left-hand side in assignment 

因此,使用null作为左侧会使这些类型的用户错误更容易被发现。

这是编译器的输出,所以程序员不可能出错 :-) - Bergi
@Bergi,这就是我说它是谨慎的做法的原因 :) 当你在两个看似不重要的选项之间做出选择时,你会选择最佳实践,即使它不会被人类接触。不能声称这一定是最初的设计思想,但它仍然是有效的。 - Rhys
编译器在编译期间可以看到您的代码,并且已经发出了许多有关问题的警告。为什么它应该对这个特定的错误保持沉默,而不是创建这个只会在运行时崩溃的装置呢?(此外,如果您尝试在http://closure-compiler.appspot.com/home编译您的代码片段,它只是扔掉整个语句,而不是执行您建议的操作...) - DCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接