我正在尝试在MySQL查询中调用一个函数,但每次调用此函数时,我都会收到:this.test不是函数
query: function(db) {
db.query("SELECT * FROM test", function(err, result, fields) {
if (err) throw err;
for (var r = 0; r < result.length; r++) {
this.test();
}
});
},
test: function(){
console.log("test");
}
我需要更改代码?
谢谢。
答案 0 :(得分:2)
您需要在闭包中捕获this
。 "that"
模式通常用于此目的:
query: function(db) {
var that = this;
db.query("SELECT * FROM test", function(err, result, fields) {
if (err) throw err;
for (var r = 0; r < result.length; r++) {
that.test();
}
});
},
test: function(){
console.log("test");
}
正如其他人正确指出的那样,您也可以使用箭头功能。然后不需要that
变量:
query: function(db) {
db.query("SELECT * FROM test", (err, result, fields) => {
if (err) throw err;
for (var r = 0; r < result.length; r++) {
this.test();
}
});
},
答案 1 :(得分:2)
在ES6(可在node.js中使用)中解决此问题的现代方法是使用回调的箭头函数定义来保留this
的值。
query: function(db) {
db.query("SELECT * FROM test", (err, result, fields) => {
if (err) throw err;
for (var r = 0; r < result.length; r++) {
this.test();
}
});
},
test: function(){
console.log("test");
}
默认情况下,任何函数调用都会根据函数的调用方式重置this
的值。因此,当db.query()
调用您的回调时,原始值this
将丢失,并且在回调中不可用。使用ES6箭头语法声明这样的回调函数专门指示Javascript解释器在执行箭头函数声明的回调时保持this
的词汇值(代码在此本地范围中具有的值)。
为了完整起见,有几种方法可以解决这个问题。
this
的值保存到您可以引用的局部变量,而不是Igor的答案显示的this
。.bind(this)
强制回调this
的值this.test()
的绑定版本,您可以在任何可以通过测试重新绑定this
的地方调用,以便您可以调用它,甚至不在回调中使用this
。在ES6之前,2和3是常见的解决方法。使用ES6,箭头功能通常是执行此操作的首选方式。
另外,请认识到:
if (err) throw err;
在异步回调内部无效或有用的错误处理。要编写好的可靠代码,您需要编写真正的错误处理,并确定在发生此类错误时应用程序应该实际执行的操作。您还可能会发现,对所有异步操作使用promises可以更容易地将异步错误传播回更容易处理它们的位置。