【问题标题】:Why does an anonymous function get called, whereas a named function doesn't?为什么匿名函数会被调用,而命名函数却不会?
【发布时间】:2025-12-27 22:25:10
【问题描述】:

我正在创建一个 CoffeeScript 应用程序,该应用程序用画布元素覆盖网络摄像头视频(这只是为了上下文,但似乎与我的问题无关)。为了让合适的画布大小覆盖在视频上,我将一个事件处理函数附加到 loadedmetadata 事件,如下所示:

WebcamWizard.prototype.initializeUserMedia = function(stream) {
  // ...
  video = document.getElementById('webcam');
  video.addEventListener('loadedmetadata', function(e) {
     // ...
     v = e.srcElement;
     // ...
  });
  // ...
}

这很好用。但是,在这种情况下,我倾向于在这个特定类的不同方法中定义这个处理程序方法,如下所示:

WebcamWizard.prototype.initializeUserMedia = function(stream) {
   // ...
   video = document.getElementById('webcam');
   video.addEventListener('loadedmetadata', this.initializeCanvas);
   // ...
}

WebcamWizard.prototype.initializeCanvas = function(e) {
   // ...
   video = e.srcElement;
   // ...
}

我喜欢这个的原因是因为它使 CoffeeScript 看起来更整洁,并允许我更轻松地访问我正在使用的类中的画布 DOM 对象。但是,当我执行第二个操作时,似乎没有调用 initializeCanvas 方法。控制台上也没有报错。这是为什么呢?

奇怪的是,以这种方式调用方法似乎在同一个文件中以完全相同的方式工作。

【问题讨论】:

  • 您是否尝试过传递WebcamWizard.initializeCanvas 而不是this.initializeCanvas
  • 很可能您在某处有异常,这两个调用语义应该无关紧要(除非@jbabey 建议,在运行时 this.initializeCanvas 与其原型之间存在某种差异)。您可以尝试捕获所有异常:developers.google.com/chrome-developer-tools/docs/…

标签: javascript coffeescript dom-events


【解决方案1】:

问题可能是“initializeCanvas”在事件发生后被调用时会丢失有用的this 引用。您正在传递对函数的引用,但 this 绑定是短暂的,将无法生存。

您可以将其包装在另一个函数中或使用.bind()

var wiz = this;
video.addEventListener('loadedmetadata', function() { wiz.initializeCanvas });

【讨论】:

  • 这是正确答案。这也表明我在文件的某些部分中对这些引用过于草率。今天学习了一些关于 JS 的新知识!