以高级模式保留原型

时间:2017-04-03 14:57:16

标签: javascript google-closure-compiler

我需要在ADVANCED模式下使用闭包编译器编译我的代码。我还需要在我的应用程序中保留我的对象的原型,因为我在Javascript对象原型上循环。尝试在启动应用程序时获得两个ReferenceError的结果。

使用ADVANCED模式进行编译时,会删除一些原型并替换为使用对象参数的函数,以便恢复"这个"关键词。这是由于CompilerOptions.java的crossModuleCodeMotionNoStubMethods属性。

编译前的代码示例:

function MyClass() = { // Some code }
MyClass.prototype.someFunc = function() { // Some code calling someOtherFunc };
MyClass.prototype.someOtherFunc = function(someParam) { // Some code };

编译后的代码示例:

function MyCompiledClass = { // Some code }
MyCompiledClass.prototype.someCompiledFunc = function() { // Some code calling someOtherFunc }
function someOtherCompiledFunc(that, someParam) = { // Some code }

我首先尝试使用@this和@preserve JSDoc标记来解决问题,但没有成功。使用@export不是解决方案,因为函数将保留其原始名称。

我现在找到了两个解决问题的方法:

  1. 将代码重构为here
  2. 构建Closure Compiler的自定义版本,如here
  3. 所示

    选项1需要对我的代码进行大量修改,并且会降低其可读性,如果它是唯一的解决方案,我将会对此进行修改。

    选项2似乎是一个很好的解决方法,但我已经读过CompilationLevel.java上的一些更改可能会违反编译器的某些核心假设。有人可以告诉我,如果将setCrossModuleMethodMotion从true修改为false,它是否仍会尊重编译器的所有核心假设?

    我目前正在构建编译器的自定义版本以检查代码是否正确编译,但即使代码可用,我也需要确保它将被正确混淆。

    谢谢!

2 个答案:

答案 0 :(得分:0)

您指的具体优化过程是DevirtualizePrototypeMethods。阻止优化的最佳方法是使用@nocollapse注释。它将允许重命名您的方法,但不允许从原型中删除它。

我并非100%确定它适用于此案例,但如果它不适用,您可以提出问题以解决此问题:https://github.com/google/closure-compiler/issues

答案 1 :(得分:0)

  

您可以以相同的方式导出构造函数和原型属性。   例如:

MyClass = function(name) {
  this.myName = name;
};
MyClass.prototype.myMethod = function() {
  alert(this.myName);
};
window['MyClass'] = MyClass; // <-- Constructor
MyClass.prototype['myMethod'] = MyClass.prototype.myMethod;

https://developers.google.com/closure/compiler/docs/api-tutorial3

一样