2013-09-27 58 views
0

中我有一個類Gadget一個方法consider定義爲:調用類方法的WebSocket對象

function Gadget() { 

    this.consider = function (arg) { 
     alert(arg); 
    }; 

    if ("WebSocket" in window) { 
     var ws = new WebSocket(...); 
     // the rest truncated 

     ws.onmessage = function (evt) { 
      consider(evt.data); 
     }; 
    } 
} 

我,但是,無法得到consider的工作,因爲它沒有一個TypeError

Uncaught TypeError: Object #<Gadget> has no method 'consider' 

如果我嘗試使用this.consider相反,TypeError發生與的WebSocket對象。如果我嘗試parent.consider,那麼對象對象給我提供了同樣的錯誤。

現在我的解決方法是使用從聲明的實例方法,如:

var player = new Gadget(); 

player.consider(evt.data)代替。我不喜歡這樣做,但它有效。我如何重新排列代碼,使其不依賴於對象的已定義實例?

+0

'var self = this; ws.onmessage = function(evt){self.consider(evt.data);};' – Passerby

+0

這會讓它在函數內可訪問,我猜?嗯,謝謝! – icedwater

回答

2

有兩種方法可以解決這個問題。

1)使用私有函數

function Gadget() { 

    function consider(arg){ 
     alert(arg); 
    } 

    this.consider = consider; 

    if ("WebSocket" in window) { 
     var ws = new WebSocket(...); 
     // the rest truncated 

     ws.onmessage = function (evt) { 
      consider(evt.data); 
     }; 
    } 
} 

這種方式,你有你的Gadget類中的私有consider()功能,即使它的實例鍛鍊自己的consider方法(如var x=new Gadget(); x.consider=...),網絡套接字仍然按照你的意圖工作;

2) 「高速緩存」 this

function Gadget() { 
    this.consider = function(arg){ 
     alert(arg); 
    }; 

    if ("WebSocket" in window) { 
     var ws = new WebSocket(...); 
     // the rest truncated 

     var self=this; 
     ws.onmessage = function (evt) { 
      self.consider(evt.data); 
     }; 
    } 
} 

這樣你的web套接字事件總是會使用任何小工具的實例想consider是。

Here is a jsfiddle demo這證明了這兩種方式。請注意,我有意地鍛鍊了(第二個按鈕)的實例的consider方法。點擊這些按鈕可以看到不同的。

+0

我在之前的評論中使用了第二種解決方案的變體。我只是在'if'塊中聲明'var self = this;'。謝謝! – icedwater

+1

@icedwater哎呀,我的壞。我的意思是把'var self = this'放在'if'裏面,但是因爲我的小提琴中沒有'if',所以我只是部分地複製了你的問題的代碼,而沒有付出太多的關注。 – Passerby