2015-06-14 134 views
1

我有這樣的代碼:this.set不是函數

var ws2812 = {}; 


ws2812.set = function(r,g,b){ 
    $.get("/light?r="+r+"&g="+g+"&b="+b, function(data) { 
     console.log("Light set to:"+"/light?r="+r+"&g="+g+"&b="+b); 
    }) 
}; 

ws2812.speech = function(word){ 
    switch(word){ 
     case "czerwone": 
      this.set(255,0,0); 
     break; 
     case "zielone": 
      this.set(0,255,0); 
      break; 
     case "niebieskie": 
      this.set(0,0,255); 
      break; 
     case "białe": 
      this.set(255,255,255); 
      break; 
     default: 
      this.set(0,0,0); 
      break; 

    } 
} 

當運行ws2812.speech("");內控制檯,一切正常。然而,當與Annyang庫配對時,我得到這個:

Uncaught TypeError: this.set is not a function 
ws2812.speech @ script.js:29 
b.annyang.init.d.onresult @ annyang.min.js:6 

怎麼了?

[編輯]

該命令被加入這樣的:

annyang.addCommands({"ustaw *term światło":ws2812.speech}); 

具體而言,內部annyang,這條線將失敗:

f[h].callback.apply(this,m) 

ws2812只有這樣,才能更換this解決這個問題?

+1

您是否將未綁定的'speech'函數作爲回調函數傳遞?請在您的示例中包含*失敗的代碼。 – zzzzBov

回答

1

ws2812.speec被定義爲靜態函數。所以this裏面的關鍵字是指它自己(功能範圍),而不是你想要的對象ws2812

要解決它,無論這些快速的選擇,可製成:


選擇#1>調用靜態函數ws2812.set正確

所以,你的代碼就變成了:

ws2812.speech = function(word){ 
    switch(word){ 
    case "czerwone": 
     ws2812.set(255,0,0); 
    break; 
    case "zielone": 
     ws2812.set(0,255,0); 
     break; 
    case "niebieskie": 
     ws2812.set(0,0,255); 
     break; 
    case "białe": 
     ws2812.set(255,255,255); 
     break; 
    default: 
     ws2812.set(0,0,0); 
     break; 

    } 
} 

但是,有一些可能性,this關鍵字在其餘部分鱈魚其他部分引用e也可能遭受這個問題。你可能需要去檢查它。


選擇#2>轉換爲原型的功能

這樣你就可以保留this關鍵字,但功能不再是靜態的。您需要實例化一個實例對象ws2812以供使用。

所以,你的聲明變成:

var ws2812 = function(){}; 


ws2812.prototype.set = function(r,g,b){ 
    $.get("/light?r="+r+"&g="+g+"&b="+b, function(data) { 
     console.log("Light set to:"+"/light?r="+r+"&g="+g+"&b="+b); 
    }) 
}; 

ws2812.prototype.speech = function(word){ 
    switch(word){ 
    case "czerwone": 
     this.set(255,0,0); 
    break; 
    case "zielone": 
     this.set(0,255,0); 
     break; 
    case "niebieskie": 
     this.set(0,0,255); 
     break; 
    case "białe": 
     this.set(255,255,255); 
     break; 
    default: 
     this.set(0,0,0); 
     break; 

    } 
} 

然後通過對象的實例,而不是使用它:

var myWs2812 = new ws2812(); 
myWs2812.speech('hello world!'); // inside it, should call this.set properly 

選擇#3>綁定 '這個' 對象調用

如果你堅持你不想修改執行程序這個ws2812。可以離開它並且綁定這個對象時使用它,而不是

因此,當您撥打ws2812.speech時,您需要使用function.prototype.call並傳入ws2812.set

ws2812.call(ws2812.set, 'hello world!'); 

然而,這看起來並不語義,它可能會導致在以後的使用混亂的人誰都會保持這種代碼。


我會留給你決定哪個是你最好的選擇。