0

我正在为我的教育阅读示例表达源代码。

初始化一个简单的 express 应用程序如下所示:

const express = require('express')
const app = express()

app.listen(3000, () => {
  console.log(`http://localhost:3000`)
})

我想了解app.listen上面代码中的内容。

源代码app.listenexpress/lib/application.js中定义,如下:

var app = exports = module.exports = {};

// ...

app.listen = function listen() {
  var server = http.createServer(this); // <-- why `this` ??
  return server.listen.apply(server, arguments);
};

通常,http.createServer()接受一个函数作为请求处理程序。在这种情况下,this是传入的。但是this应该引用app,它不是一个函数,对吧?

后来我发现app.handle被用作请求处理程序。

引擎盖下发生了什么?

谢谢你的时间!

4

1 回答 1

1

thisapp原型的增强实例,它被用作http.createServer. 要追查这样的答案,我们需要充分了解 Node 的 CommonJS 模块实现、JavaScript 原型继承系统和 JavaScript 函数范围。

答案就在这些线后面: https://github.com/expressjs/express/blob/4.16.3/lib/application.js#L38 https://github.com/expressjs/express/blob/4.16.3/ lib/express.js#L43

app是一个指向 的指针module.exports,它表示该模块如何与其他 Node 模块进行交互。该模块由 Express 在 lib/express 内部使用,在实例化之前它与另一个 JavaScript 原型混合在一起。一旦一个实例,applib/application 中的每个函数都共享一个this,可以用来引用其原型上的每个属性值和函数。

所以...

因为http.createServer接受一个选项对象作为它的第一个参数,如果可用,ServerResponse&IncomingMessage将从app/中this使用。

PS不要像Express 团队那样编写代码。您永远不需要查看多个模块来找到这样一个简单问题的答案。有更简单和团队友好的方法来模块化原型混合和默认初始化选项!

于 2018-08-23T10:19:10.077 回答