2015-06-14 2 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) 

ли замена this с ws2812 единственным способом обойти это?

+1

Вы передаете несвязанную функцию 'speech' как обратный вызов? Пожалуйста, укажите код, который * не удается * в вашем примере. – zzzzBov

ответ

1

ws2812.speec определяется как статическая функция. Таким образом, ключевое слововнутри него относится к самому себе (функция scope), а не к объекту 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 также может пострадать от этой проблемы. Вам может потребоваться проверить это.


Choice # 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 

Choice # 3> Bind 'этот' объект при вызове

Если вы настаиваете, что не хотите изменять реализацию ws2812. Это нормально, и связывает этот объект при его использовании.

Поэтому, когда вы звоните ws2812.speech, вам необходимо использовать function.prototype.call и передать ws2812.set.

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

Однако это не выглядит многословным, и это может вызвать недоумение в будущем для людей, которые будут поддерживать этот код.

Я оставлю это для вас, чтобы решить, какой из них будет лучшим для вас.

Смежные вопросы