老式 JavaScript 类 和高级 JS 缩小问题

old-school JavaScript classes and advanced JS minification issue

我有一个相当精致的 class,它使用旧式的方式创建 classes。不是使用 class 关键字,而是使用 function 关键字定义 classes。要创建 public 属性,请分配 this.publicProperty。我的代码运行良好。

然而,当我尝试在 高级 模式下使用 Closure Compiler(一种 JS 缩小工具)时,我遇到了无数错误,从一个关于 'dangerous' 引用 this。这是一个简单的例子,它说明了我的问题。我尝试压缩这个琐碎的 JS 代码:

var myclass = function(p1, p2) {
    this.publicProperty = null;
};

Compiled Code 输出为空,并出现警告:

JSC_USED_GLOBAL_THIS: dangerous use of the global this object at line 2 character 2
this.publicProperty = null;
^

为什么会这样'dangerous'?

我在 SO 上看到 other posts,这清楚地表明我的代码似乎没问题。为什么 Closure minifier 会抱怨这个?

作为第二个问题,我想知道是否有人可以推荐一个有效的基于浏览器的 JS 压缩器,它将您的 JS 压缩为一行代码。我已经尝试过 Uglifier 和 Closure,但 javascript-minifier 无法获得只有一行代码的缩小 JS 输出。

总结编辑和讨论如下:闭包编译器依赖注释作为指令。所以注释构造函数(如下所示)是一个开始。接下来,还需要意识到任何未被您同时编译的任何其他代码使用的代码都将被视为 死代码 并将被删除编译器。这不适用于像您这样的自定义 API。所以最后的修复(也在下面)是使用数组类型 属性 访问符号( [] ).

在 window 对象上记录对函数的引用

编辑 我错过了一个重要的细节。由于您使用的是 advanced 模式,因此请遵照 Chad 下面的评论,Chad 说: 如果您使用 ADVANCED 模式,则存在一个单独的问题 - 从未使用过构造函数,因此将其作为死代码删除。所以请确保您的构造函数在您的代码中得到解决。

编辑 3 要解决 Chad 引用的问题(他的名字到处都是错误报告!),下一步是将您的函数添加到全局范围。无论如何它似乎都驻留在全局中,所以这不是什么大问题(除非你纠正我)。

window['myClass'] = myClass;

====

要解决您的问题,您必须正确注释您的代码。听起来好像情况并非如此。这是一个相关的片段 from the docs:

@constructor

Marks a function as a constructor. The compiler requires a @constructor annotation for any function that is used with the new keyword. @constructor should be omitted from EcmaScript class constructor methods and goog.defineClass constructor methods.

使用此代码示例:

/**
 * A rectangle.
 * @constructor
 */
function GM_Rect() {
  ...
}

所以用你的示例代码试试这个:

    /**
     * @constructor
     */
    var myclass = function(p1, p2) {
        this.publicProperty = null;
    };

这应该可以解决问题。您可能必须使用命名函数而不是函数表达式。