闭包编译器并不总是内联枚举。为什么?

Kar*_*arl 5 javascript enums google-closure-compiler

enumGoogle 的闭包编译器在决定 an是否内联时遵循哪些规则?

当我通过闭包编译器运行代码时,JSDoc注释 enum类型未内联。然而,当我创建一个简化的示例时,enum类型是内联的,正如这个无意义的示例将演示的那样:

 var my_name_space = (function () {
     'use strict';

     /** @enum {number} */
     var TASK_STATUS = {
         REJECT: -1,
         UNKNOWN: 0,
         APPROVE: 1
     };

     function init_(a) {
         if (a === TASK_STATUS.UNKNOWN) {
             alert("Reject");
             a = TASK_STATUS.REJECT;
         } else if (a === TASK_STATUS.APPROVE) {
             alert("Unknown");
             a = TASK_STATUS.UNKNOWN;
         } else {
             alert("Approve");
             a = TASK_STATUS.APPROVE;
         }
         return a;
     }
     return { init: init_};

 }());  // my_name_space


 my_name_space.init(-1);
Run Code Online (Sandbox Code Playgroud)

闭包的输出:

 var my_name_space=function(){return{init:function(a){0===a?(alert("Reject"),a=-1):1===a?(alert("Unknown"),a=0):(alert("Approve"),a=1);return a}}}();my_name_space.init(-1);
Run Code Online (Sandbox Code Playgroud)

事实上,无论有没有 JSDoc 标头,内衬都会发生。

请解释在什么条件下衬里不会发生,或者更好的是,请对上述内容进行修改,以证明衬里何时不会发生。

我正在使用“简单”优化级别。

Joh*_*ohn 4

首先,枚举并不是真正用于优化目的的特殊对象,但是,@enum 对于类型检查很有用,并且为此目的有特殊规则。

至于内联,有很多事情会阻止内联,展示所有可能性是不合理的,但我可以告诉你为什么它们可能不会:

  • 枚举对象被定义为对象的属性,不能分解为变量(高级模式在这里有帮助)
  • 枚举是在全局变量上定义的(高级模式在这里有帮助)
  • 枚举对象以别名本身无法删除的方式设置别名(将枚举对象传递给无法内联的函数,将枚举对象分配给全局值)。
  • 迭代枚举键/值(for-in 等)
  • 枚举对象被覆盖

这些都归结为编译器无法确定它可以:

  • 删除对象并将其替换为单独的值
  • 内联这些值

也就是说,如果您有一个简单的本地定义,并且您只引用值而不引用对象本身,并且值本身是简单的常量(数字、布尔值),那么它总是会被内联。