this.set不是一个函数

时间:2015-06-14 16:52:47

标签: javascript annyang

我有这样的代码:

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 个答案:

答案 0 :(得分:1)

ws2812.speec被定义为静态函数。所以this里面的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; } } 关键字指的是它自己(函数范围),而不是你想要的对象 ws2812

要解决这个问题,可以选择以下任何一种快速选择:

选择#1>正确调用静态函数ws2812.set

所以你的代码变成了:

this

但是,在其他代码的其他部分中引用的this个关键字也可能会遇到此问题。你可能需要去检查一下。

选择#2>转换为原型函数

这样您就可以保留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

然后通过对象的实例使用它:

ws2812

选择#3>在调用

时绑定'this'对象

如果您坚持要求您不想修改此ws2812.speech的实施。可以保留它并在使用它时绑定此对象

因此,当您致电function.prototype.call时,您需要使用ws2812.set并传递ws2812.call( ws2812.set, 'hello world!' );

var donotcountP = ':has(.warning):contains(P)';
var donotcountS = ':has(.warning):contains(S)';
var donotcountO = ':has(.warning):contains(O)';

$('.two_column_layout').find("td.player:not("+donotcountP+"):not("+donotcountS+"):not("+donotcountO+")").css('background', 'red');

然而,这看起来并不太语义,并且可能会导致对将来维护此代码的用户产生混淆。

我会留下让你决定哪种方式最适合你。