4

我有一个相当精细的类,它使用旧式的创建类的方式。不是使用类关键字,而是使用函数关键字定义类。要创建公共属性,请分配this.publicProperty。我的代码运行良好。

然而,当我尝试在高级模式下使用Closure Compiler(一个 JS 压缩工具)时,我得到了无数错误,从一个关于对this的“危险”引用开始。这是一个简单的例子,它说明了我的问题。我尝试压缩这个简单的 JS 代码:

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

编译后的代码输出为空并且有一个警告:

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

为什么这是“危险的”?

我在这里看到了关于 SO 的其他 帖子,这些帖子清楚地表明我的代码看起来不错。为什么 Closure minifier 抱怨这个?

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

4

1 回答 1

2

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

编辑 我错过了一个重要的细节。遵从 Chad 下面的评论,因为您使用的是高级模式,Chad 说:如果您使用 ADVANCED 模式,则存在一个单独的问题 - 构造函数永远不会被使用,因此它被作为死代码删除。所以请确保你的构造函数在你的代码中被寻址。

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

窗口['myClass'] = myClass;

====

要解决您的问题,您必须正确注释您的代码。听起来情况可能并非如此。这是来自文档的相关片段:

@构造函数

将函数标记为构造函数。对于与 new 关键字一起使用的任何函数,编译器都需要 @constructor 注释。@constructor 应该从 EcmaScript 类构造方法和 goog.defineClass 构造方法中省略。

使用此代码示例:

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

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

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

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

于 2018-03-01T17:39:42.937 回答