JavaScript 导入模块混淆
Posted
技术标签:
【中文标题】JavaScript 导入模块混淆【英文标题】:JavaScript importing module confusion 【发布时间】:2022-01-24 03:49:13 【问题描述】:当我导入“http”模块时,我使用
Var http = require('http');
http.createServer(function(req,res)......
.listen(8080)
但是当我导入 express 模块时,我使用
const express = require('express');
const app = express();
app.get('/', (req,res)=>........
app.listen()
为什么我需要在代码中创建const app = express();
而不是const app = http();
?
【问题讨论】:
因为 express 有构造函数而 http 没有。与导入无关 【参考方案1】:express
从模块中导出一个函数。 http
导出具有函数的对象。
每个库作者都选择自己的方式来导出他们的库。
这是一个如何实现它们的示例。
module.exports = function()
// code here
return
// calling the function returns an object
module.exports =
createServer()
【讨论】:
【参考方案2】:您的任何问题都与导入无关。
当你这样做时:
const app = express();
您正在创建 Express 类的实例。 express
函数是一个工厂函数,当您调用它时会创建一个对象(在这种情况下,它是一个函数对象)。它不是 http 服务器。它既是一堆方法的父对象,又是路由传入 http 请求的主要请求处理程序。
当你这样做时:
app.listen()
这将创建您的 http 服务器。实际上,.listen()
方法中的代码只是为您创建了 http 服务器并将 app
注册为传入连接的请求处理程序。
如果您查看code 对应的app.listen()
,您只会看到:
app.listen = function listen()
var server = http.createServer(this);
return server.listen.apply(server, arguments);
;
它只是创建一个以app
函数/对象作为主要请求处理程序的http 服务器实例,然后它调用.listen()
来启动服务器。
所以,app.listen()
只是一个捷径。您可以自己使用http
模块来创建自己的服务器对象,然后使用它注册您的app
对象,但app.listen()
只是为您做这些。
作为教学替代方案,还有许多其他方法可以安排代码。你也可以这样做:
const express = require('express'); // load express module
const app = express(); // create express instance
const http = require('http'); // load http module
const server = http.createServer(app); // create http server
// and register express listener
server.listen(80); // start http server
这不会利用app.listen()
中的快捷方式,但效果相同。
【讨论】:
谢谢,如果 express 是一个类,那么为什么 const app = express(); 中没有“new”比如 const app = new express(); @Aakash - 正如我所说,express()
函数是一个工厂函数。它创建对象本身的一个实例。它在该函数中执行new
。它不直接公开类构造函数。相反,您调用工厂函数来获取该类的新实例。这是创建某个类的新实例的一种设计模式。它可能是这样实现的,因为 Express 在 javascript 具有 class
语法之前就已经存在,但偶尔更喜欢工厂函数还有其他原因。以上是关于JavaScript 导入模块混淆的主要内容,如果未能解决你的问题,请参考以下文章
将 Vue npm 模块导入我的 javascript 文件
在 JavaScript 模块中正确导入 Firebase 存储