为什么匿名函数会被调用,而命名函数不会?

3

我正在创建一个基于CoffeeScript的应用程序,该应用程序使用Canvas元素叠加在Webcam视频上(这仅仅是为了提供上下文信息,似乎与我的问题无关)。为了获得正确的Canvas尺寸以覆盖视频,我将事件处理函数附加到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代码更加整洁,并且可以更轻松地在我正在使用的类中访问canvas DOM对象。但是当我采用第二种方式时,initializeCanvas方法似乎没有被调用。控制台也没有报告任何错误。为什么会这样呢?
奇怪的是,在同一文件中以这种方式调用方法似乎也可以正常工作。

дҪ иҜ•иҝҮдј йҖ’WebcamWizard.initializeCanvasиҖҢдёҚжҳҜthis.initializeCanvasеҗ—пјҹ - jbabey
很可能你的代码出现了异常,两种调用语义不应该有影响(除非像@jbabey所建议的那样,在this.initializeCanvas和其原型之间在运行时出现差异)。你可以通过以下方式尝试捕获所有异常:https://developers.google.com/chrome-developer-tools/docs/scripts-breakpoints#js_exceptions - Eric
1个回答

5
问题可能是当事件发生后调用"initializeCanvas"时,缺少一个有用的“this”引用。虽然你传递了函数的引用,但是“this”绑定是短暂的,不会保留下来。
你可以将其包装在另一个函数中或使用".bind()":
var wiz = this;
video.addEventListener('loadedmetadata', function() { wiz.initializeCanvas });

这是正确的答案。它还向我展示了在文件的某些部分中,我的引用太草率了。今天学到了有关JS的新知识! - DCKing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接