当你这样做时:
let x = require('someModule');
x 的值是模块在模块中设置module.exports 值的任何值。它可以是任何东西。这完全取决于模块分配给它的内容。它通常是一个对象(带有属性),但它也可以是一个函数,有时甚至是一个带有属性的函数。
要查看 socket.io 分配给module.exports 的内容,我们可以直接转到我们看到的the source:
module.exports = Server;
那么,那我们去看看Server是什么,找到this:
function Server(srv, opts){
if (!(this instanceof Server)) return new Server(srv, opts);
if ('object' == typeof srv && srv instanceof Object && !srv.listen) {
opts = srv;
srv = null;
}
opts = opts || {};
this.nsps = {};
this.parentNsps = new Map();
this.path(opts.path || '/socket.io');
this.serveClient(false !== opts.serveClient);
this.parser = opts.parser || parser;
this.encoder = new this.parser.Encoder();
this.adapter(opts.adapter || Adapter);
this.origins(opts.origins || '*:*');
this.sockets = this.of('/');
if (srv) this.attach(srv, opts);
}
由此我们可以看出它是一个构造函数,可以被调用为:
const x = new Server(...);
或作为:
const x = Server(...);
所以,答案如下:
require('socket.io') 给你一个构造函数。
该构造函数可以使用new 调用,也可以作为普通函数调用,它适应返回相同的东西,一个新的服务器对象。
所以,当你这样做时:
const server = require('socket.io')();
它首先获取导出的构造函数,然后调用它并将新创建的对象分配给server变量。
1)什么是socket.io(它是一个类还是接口我检查了node.js中的文档它应该是接口)
服务器上的socket.io 导出了一个构造函数来创建一个服务器对象。它可以作为常规函数调用,也可以通过new 调用。
2)如果是接口,我认为我们必须使用类来使用它(我没有看到任何文档在 javascript 中实现接口)
这是一个函数。 Javascript 没有称为接口的特定类型。 socket.io 代码以老式的方式(在class 关键字存在之前)定义了一个构造函数,尽管结果基本相同。它定义了一个构造函数,当被调用时将创建一个所需类型的对象。
3) 现在我很困惑如何实现套接字以及以下两种语法如何相等
在 Javascript 中,这两段不同的代码创建了相同的 server 对象:
const io = require('socket.io');
const server = io();
和
const server = require('socket.io')();
第二个只是一个快捷方式,它不会将来自require('socket.io') 的中间结果分配给变量,而是直接调用它。只有当第一个函数调用返回一个函数时,它才会像这样工作。因此,第一个语法获取一个函数,将其分配给io 变量,然后调用它。第二种语法获取函数并立即调用它而不将其分配给变量。在这两种情况下,获取函数并调用它的结果都会在 server 变量中结束。