2012-07-09 124 views
3

我正在創建一個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的看整潔的原因,讓我來訪問我正在更輕鬆地處理類中的canvas DOM對象。但是,當我做第二個時,initializeCanvas方法似乎不被調用。在控制檯上也沒有錯誤報告。這是爲什麼?

奇怪的是,以這種方式調用方法似乎在同一個文件中以完全相同的方式工作。

+0

你試過路過的'WebcamWizard.initializeCanvas'代替'this.initializeCanvas'? – jbabey 2012-07-09 14:35:47

+0

很可能你在某處有異常,這兩個調用語義應該沒有關係(除非@jbabey表明,在運行時在this.initializeCanvas和它的原型之間有某種不同之處)。您可以嘗試捕獲所有異常:https://developers.google.com/chrome-developer-tools/docs/scripts-breakpoints#js_exceptions – Eric 2012-07-09 14:40:19

回答

5

問題可能是「initializeCanvas」在事件發生後調用它時會丟失有用的this引用。您正在傳遞該函數的引用,但綁定是短暫的並且不會生存。

您可以在另一個函數把它包起來,或使用.bind()

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

這是正確的答案。它也表明我在文件的某些部分對這個引用太過於草率。今天學到了關於JS的新東西! – DCKing 2012-07-09 14:44:32

相關問題