NodeJS 在Express模块中使用变量两次,但在其它模块中仅使用一次

cyej8jka  于 2023-01-25  发布在  Node.js
关注(0)|答案(4)|浏览(157)

下面是使用任何Node.js模块的简单语法

let os = require('os');

console.log("This is the user info - " , os.userInfo());

现在,我们看到,要使用os模块中已经存在的函数,我们只需要使用简单的点标记法,我们通过写os.userInfo()得到它。
但是,如果使用Express.js,以下是程序:-

let express = require('express');          // 
let app = express();           //  Line 1

app.listen(\\Write_Code);

我想知道为什么我们要写let app = express();,如果我们使用Express.js,毕竟,我们也导入express模块,所以我们应该能够像express.app.listen()express.listen()一样使用它的函数,我知道app是Express模块中的一个变量,但是我不明白为什么我们要写let app = express();,谁能告诉我写let app = express();的时候发生了什么

nhn9ugyo

nhn9ugyo1#

它创建Express应用程序的一个示例,该示例是Express函数或类,是Express模块的主导出。
let app = express()中创建的app变量是一个Express示例,它有处理各种HTTP请求的方法(例如app.get()、app.post()),也有设置和中间件。
通过创建Express应用程序的示例,您可以将app变量作为参数传递,从而在函数之外添加路由和中间件。
如果您的Express不需要任何花哨的自定义或动态加载中间件,也可以使用one-liner方法创建Express服务器。

Express()
    .use(Express.json())
    .all('*', (req, res) => {
        res.send('Hello World')
    })
    .listen(8080)
2ul0zpep

2ul0zpep2#

你在比较两个不同的东西,当你需要os时,它会给你一堆函数,这些函数可以在一个示例对象中访问,为了简化这个过程,想象一下它是这样的:

// os module

exports.userInfo = () {};
exports.cpus = () {};
...

无论何时你需要或导入这个模块,它都会给你这样的对象:

{
  userInfo() {},
  cpus() {}, 
  ...
}

但是express的情况下,结构有点不同,你需要的时候,它给你一个default function和一些其他的方法,通过调用默认函数,它给你一个对象,你可以在这个对象中创建自己的服务器,使用中间件等,在app方法下可以访问它,但是它也给你一些不在app下的函数,如jsonstatic等,因此这意味着可以在不调用默认函数(即express.json)的情况下调用它们。
这类似于 OOP 原则,在类的情况下,你可能已经定义了一些方法和一些 static 方法。static 方法不需要创建类的示例就可以访问(例如jsonstatic)。但是类有一些其他的方法,我们必须创建类的示例来访问它们(例如uselisten)。
在代码中,它将是这样的:

// express

exports = module.exports = () => {}; // this is necessary for defining default function.
exports.json = () => {};
exports.static = () => {};
...

当你需要它时,它会给你这个:

[Function: () => {}] { json() {}, static() {} }

虽然Express目前的实现实际上并不是一个类,但是在我看来,可以用类来代替它,目前的方法叫做factory functionconstructor 函数和 factory 函数之间有一些区别,你可能需要阅读更多的相关内容(Constructor function vs Factory functions和把异步操作放在构造函数中特别困难)。

bd1hkmkf

bd1hkmkf3#

我个人并不熟悉Express的源代码,但是quick peek on Github可以快速揭示正在发生的事情,以防从您必须编写的代码中看不出来。
从该模块导出为express的内容实际上在内部称为createApplication

function createApplication() {
  var app = function(req, res, next) {
    app.handle(req, res, next);
  };

  mixin(app, EventEmitter.prototype, false);
  mixin(app, proto, false);

  // expose the prototype that will get set on requests
  app.request = Object.create(req, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  // expose the prototype that will get set on responses
  app.response = Object.create(res, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  app.init();
  return app;
}

虽然我不能解释这个函数的所有细节(因为我也不知道它们),但很明显,这个函数不接受任何参数,返回一个表示应用程序的对象,因此在使用代码时通常称为app
至于为什么它以这种方式工作而不是你想要的方式--这是那些最初制作Express的人的问题。我不明白为什么从技术上讲它不能以这种方式工作--让createApplication中的代码在模块的顶层运行,然后导出app对象。实际方法的一个优点是,您可以通过在消费代码中执行以下操作,同时“示例化”多个应用:

let express = require('express');
let app1 = express(); 
let app2 = express();

然后用app1app2做一些事情,它们将完全独立于彼此。至于这是否对任何人都有用,我不知道--但为了在需要的地方获得这种灵活性,只需要支付少量的一次性额外代码,这似乎是一个非常小的代价。

ddhy6vgd

ddhy6vgd4#

express是一个“类“1,您可以通过重复调用express()来创建它的 * 许多 * 示例。express的示例也称为app.listen方法存在于 * 示例 * 上,即app上,因为不同的示例(不同的app)可以不同的方式侦听,例如在不同的端口上。
相比之下,express.static是一个只存在一次的中间件,因此是express对象的静态属性,appapp之间没有区别。
os.userInfo同样是静态的,因为作为用户,您不能同时观察操作系统的多个示例。
1我在阅读了评论之后把class放在引号里,但事实上你可以用它创建几个示例。

相关问题