Closure Compiler显然用不正确的三元表达式替换条件

时间:2017-02-07 19:05:32

标签: google-closure-compiler

我有以下测试:

goog.provide('testing.Test');

goog.require('goog.array');

/**
 * @constructor
 */
testing.Test = function() {
  /**
   * @type {!Array.<number>}
   * @private
   */
  this.array_ = [];
};

/**
 * @enum {number}
 */
testing.Test.Constant = {
  ZERO: 0,
  ONE: 1
};

testing.Test.prototype.run = function() {
  if (goog.array.peek(this.array_) === testing.Test.Constant.ZERO) {
    console.log('last item matches ZERO');
  } else {
    console.log('last item does not match ZERO');
  }
};

var test = new testing.Test();

console.log(test.run());

使用默认优化进行编译并运行会产生预期结果:

&#34;最后一项与ZERO&#34;

不匹配

但是,使用ADVANCED_OPTIMIZATIONS进行编译并运行会产生意外结果:

&#34;最后一项与ZERO&#34;。

相匹配

我已将问题追溯到优化编译的输出:

function b(){this.a=[]}console.log(function(){var a=(new b).a;a[a.length-1]?console.log("last item does not match ZERO"):console.log("last item matches ZERO")}());

编译器似乎正在用三元替换条件,但是删除了等式检查。

这是预期的行为,如果是,我错过了什么?

我正在通过版本20170124.0.0 NPM软件包运行编译器和库。但是,我从NPM测试的每个版本的编译器都给出了相同的结果。

我有一个旧版本的编译器jar文件,但没有显示该行为。我的笔记表明,这个版本是我在2016年6月初从源头下载或编译的。

1 个答案:

答案 0 :(得分:2)

这是基于类型的优化。编译器可以检测到数组永远不会更改。在数组边界外读取被认为是无效的。

你可以:

  1. 将数组声明为类型Array<number|undefined>
  2. 使用--use_types_for_optimization=false
  3. 禁用基于类型的优化

    请参阅https://github.com/google/closure-compiler/issues/2136