this.set 不是函数
this.set is not a function
我有这样的代码:
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
是解决此问题的唯一方法吗?
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
关键字也有可能遇到此问题。你可能需要去看看。
选择#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 > 调用时绑定'this'对象
如果您坚持不想修改此 ws2812
的实现。可以留下,使用时绑定这个对象.
所以当你调用ws2812.speech
时,你需要使用function.prototype.call
并像这样传入ws2812.set
。
ws2812.call( ws2812.set, 'hello world!' );
但是,这看起来语义不多,可能会在将来维护此代码的人员的使用中造成混淆。
我会留给你决定哪条路最适合你。
我有这样的代码:
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
是解决此问题的唯一方法吗?
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
关键字也有可能遇到此问题。你可能需要去看看。
选择#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 > 调用时绑定'this'对象
如果您坚持不想修改此 ws2812
的实现。可以留下,使用时绑定这个对象.
所以当你调用ws2812.speech
时,你需要使用function.prototype.call
并像这样传入ws2812.set
。
ws2812.call( ws2812.set, 'hello world!' );
但是,这看起来语义不多,可能会在将来维护此代码的人员的使用中造成混淆。
我会留给你决定哪条路最适合你。