无法获取功能以外范围

问题描述:

我试图调用一个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"); 
} 

做什么我需要更改我的代码?

谢谢。

您需要在关闭中捕获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(); 
     } 
    }); 
}, 

现代的方式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(代码在本地作用域中的值)的词汇值。


为了完整起见,有几种方法可以解决这个问题。

  1. 使用箭头功能declaraing回调,而不是常规的函数声明
  2. 保存的this来,你可以参考,而不是this这就是伊戈尔的回答显示了一个局部变量的值。
  3. 在回调使用.bind(this)来强制回调
  4. this值创建的this.test()一个绑定的版本,您可以在任何地方调用与测试重新绑定this这样你就可以调用,甚至无法使用this回调中。

在ES6,2和3之前是常用的解决方法。有了ES6,箭头功能通常是这样做的首选方式。


同时,请意识到:

if (err) throw err; 

异步回调里面是不是有效的或有用的错误处理。要编写好的可靠代码,您需要编写真正的错误处理并确定应用程序在出现此类错误时应实际执行的操作。您也可能会发现,对所有异步操作使用promise可以更轻松地将异步错误传播回容易处理它们的地方。

+0

@FSantos - 既然你接受了'var that = this'这个答案,我想确保你看到了其他的选项,包括ES6箭头声明,这些选项真的是现在更受欢迎的选项。 – jfriend00