Javascript Express并以无点方式调用response.json不会';I don’’那么,我不会答应的

Javascript Express并以无点方式调用response.json不会';I don’’那么,我不会答应的,javascript,express,pointfree,Javascript,Express,Pointfree,今天有件事让我大吃一惊。我遇到了一堆express route处理程序,基本上是这样的(有更多真实的函数调用,但为了清晰起见: app.get('/api/foo', (req, resp) => { Promise.resolve({one: 1}) .then(data=>resp.json(data)) }) 因此,作为一名聪明的javascript程序员,我认为我可以远离匿名函数,让该函数直接调用resp.json: app.get('/api/foo', (r

今天有件事让我大吃一惊。我遇到了一堆express route处理程序,基本上是这样的(有更多真实的函数调用,但为了清晰起见:

app.get('/api/foo', (req, resp) => {
  Promise.resolve({one: 1})
    .then(data=>resp.json(data))
})
因此,作为一名聪明的javascript程序员,我认为我可以远离匿名函数,让该函数直接调用resp.json:

app.get('/api/foo', (req, resp) => {
  Promise.resolve({one: 1})
    .then(resp.json)
})
但当我尝试这样做时,我从未得到响应,并在节点控制台中看到:

未处理的承诺拒绝(拒绝id:1):TypeError:无法读取 未定义的属性“app”


在我看来,.then(resp.json).then(data=>resp.json(data))应该是等效的。这是一个范围问题,可以肯定,但我希望有一个解释,也许还有一个解决办法。

这是因为
resp
是一个具有自己属性的对象,因此
json
函数使用的数据很可能包含在
resp
对象中

当您将函数
resp.json
本身传递给
then
时,您没有传递
resp
对象或其任何信息。本质上,
then
调用只是“借用”函数
json
来自
resp
对象
。但只包含函数体本身,没有作用域或隐式值

更有可能的是,
json
的函数体在某处使用了
this
,此时您将得到一个无效(可能是全局)对象,而不是
resp

要补救,你可以这样做

   Promise.resolve({one: 1})
    .then(resp.json.bind(resp))

它们不一样是因为它们的方式不同

基本上,
resp.json(data)
使用
this==resp
调用函数,而
resp.json
使用
this==global
调用函数


若要修复此问题,请使用绑定参数传递函数。然后(resp.json.bind(resp))(或使用箭头函数)。

Ha.您是对的。我刚刚解决了这个问题。谢谢!但是这样很难看,最好使用胖箭头函数。