【问题标题】:Javascript Dot-Syntax function disappears in listen callbackJavascript点语法函数在监听回调中消失
【发布时间】:2019-08-31 17:19:54
【问题描述】:

我正在尝试将 Annotorious (https://annotorious.github.io/#) 更新到最新版本的 Closure / Javascript。

当我使用“简单”优化对其进行编译时,点语法函数在调用 goog.events.listen 回调时似乎消失了。这是一个例子:

这里是“主要”:

goog.provide('annotorious.Annotorious');
...
/**
 * The main entrypoint to the application. The Annotorious class is instantiated exactly once,
 * and added to the global window object as 'window.anno'. It exposes the external JavaScript API
 * and internally manages the 'modules'. (Each module is responsible for one particular media
 * type - image, OpenLayers, etc.)
 * @constructor
 */
annotorious.Annotorious = function() {
  /** @private **/
  this._isInitialized = false;

  /** @private **/
  this._modules = [ new annotorious.mediatypes.image.ImageModule() ];
...

在另一个文件中(它们都编译在一起),我们有这个:

goog.provide('annotorious.Annotation');

goog.require('annotorious.shape');

/**
 * A 'domain class' implementation of the external annotation interface.
 * @param {string} src the source URL of the annotated object
 * @param {string} text the annotation text
 * @param {annotorious.shape.Shape} shape the annotated fragment shape
 * @constructor
 */
annotorious.Annotation = function(src, text, shape) {
  this.src = src;
  this.text = text;
  this.shapes = [ shape ];
  this['context'] = document.URL; // Prevents dead code removal
}

所以我们启动代码,在某个时候我们在编辑器中结束注释,监听“保存”按钮:

goog.provide('annotorious.Editor');

....

/**
 * Annotation edit form.
 * @param {Object} annotator reference to the annotator
 * @constructor
 */
annotorious.Editor = function(annotator) {
  this.element = goog.soy.renderAsElement(annotorious.templates.editform);

....
  /** @private **/
  //this._btnSave = goog.dom.query('.annotorious-editor-button-save', this.element)[0];
  this._btnSave = this.element.querySelector('.annotorious-editor-button-save');
...
  goog.events.listen(this._btnSave, goog.events.EventType.CLICK, function(event) {
    event.preventDefault();
    var annotation = self.getAnnotation();
    annotator.addAnnotation(annotation);
    annotator.stopSelection();

    if (self._original_annotation)
      annotator.fireEvent(annotorious.events.EventType.ANNOTATION_UPDATED, annotation, annotator.getItem());
    else
      annotator.fireEvent(annotorious.events.EventType.ANNOTATION_CREATED, annotation, annotator.getItem());
    self.close();
  });

如果我在“goog.events.listen(this._btnSave...”处设置断点并输入“annotorious.Annotation”,我会得到预期的结果:

其实它有各种各样的方法:

然后我放开代码,并在监听器中中断(event.preventDefault();等,如上):

现在,所有的点语法方法都消失了。

这当然会导致以后崩溃。

所有这些文件都是一起编译的。

所有回调都会发生这种情况 - “加载”事件、其他用户体验回调等。

这必须在先前版本的 Closure / JS 中有效。

这可能是什么原因造成的?

谢谢!

【问题讨论】:

  • 我的猜测是在覆盖命名空间的一部分之后加载了一些东西。 goog.provide 的一个经典问题是,它是按字面量构建命名空间对象。 // file-1 goog.provide('a');一个=一些对象; // file-2 goog.provide('a.b'); a.b = someOtherThing;如果首先加载 file-2(隐式创建“a”)然后加载 file-1,则 file-1“a”不会保留任何属性。
  • 通过观察生成的代码,我确信这是问题的一部分。我间接解决了它(见下文)。谢谢!

标签: javascript google-closure-compiler google-closure-library


【解决方案1】:

好的,我可以通过在闭包编译器命令行中添加“--assume_function_wrapper”来解决问题。

以前,我使用 Plovr 编译包。然而,由于 Plovr 很久没有更新了,我转而使用原生的闭包编译器。

显然,Plovr 内部提供了“--assume_function_wrapper”Plovr 使用的编译器版本没有破坏所描述的函数。

正如@john 建议的那样,我敢打赌'--assume_function_wrapper' 通过重新声明它们来防止goog.provide“破坏”命名空间。

【讨论】:

  • "assume_function_wrapper" 在“简单”模式下启用全局优化(否则必须假定全局已导出。还可以考虑提供与全局范围隔离的“isolatione_mode=IIFE”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 2021-06-07
相关资源
最近更新 更多