在Node.js中使用“require()”会发生什么?

时间:2018-04-23 01:55:35

标签: javascript node.js

很抱歉,如果这是一个愚蠢的问题,但我是JavaScript / Node.js的新手。下面的代码使我无法完成,我已经做了一些研究......我的下面的问题更具体地与实例化有关。

我不明白这一点:

var myApp = require('express'); 
var myCode = myApp();

我如何看待它应该用于实例化:

var myApp = new Express();
var myCode = myApp.insideExpress();

匿名函数表达式如何:

var myApp = function();
var myCode = myApp();

如果单词“ require ”作为一种匿名函数表达式,那么事情如何在后台实例化?这对于制作合适的图案非常重要,不是吗?

我的问题是:

  1. 第一个例子的后台发生了什么,是JavaScript / Node.js实例化/构建还是根本没有?
  2. 这样做的人只是创造了糟糕的模式吗?我为什么要使用这种模式?
  3. 如果没有实例化,为什么不呢?
  4. 提前致谢

2 个答案:

答案 0 :(得分:5)

const myVar = require("someModule")从文件系统加载模块,运行模块初始化代码并将模块导出分配给您的变量。模块加载子系统维护一个缓存,因此如果它先前已加载,则不会加载或再次运行,模块的导出只是从缓存中检索并分配给您的变量。

所以,当你这样做时:

var myApp = require('express');      // load express module, assigns exports to myApp
var myCode = myApp();                // calls myApp() function and assigns result to myCode

第一行加载快速模块,并将该模块的导出分配给myApp变量。在这种特殊情况下(因模块而异),Express模块​​的导出是一个功能。因此,在第一行代码之后,myApp包含一个函数,该函数恰好是用于创建新的Express应用程序对象的工厂函数。

第二行代码调用返回新的Express app对象的工厂函数。

模块可以导出任何想要的东西。在上面的例子中,它导出了一个函数,但是导出一个具有大量属性然后可以访问的对象也很常见。您还可以导出构造函数,在这种情况下,调用者将使用new和构造函数从中创建一个新对象。

在Express模块​​中,它没有导出构造函数(这就是你不使用new的原因)。相反,它决定导出一个工厂函数,在调用时,它创建并返回一个新对象。这只是一个设计决策,可以根据模块的需要和代码编写者的想法进行两种方式。

我无法用这段代码告诉你这里有什么问题:

var myApp = new Express();          // the express module does not export a constructor
var myCode = myApp.insideExpress();

仅当Express是构造函数时,这才有效。快速模块本身不会选择导出构造函数,因此这不是您使用快速模块的方式。它可以这样设计,但事实并非如此。他们在设计时只是做出了不同的设计决定。

对于这个其他情况,你会显示:

var myApp = function();
var myCode = myApp();

第一行代码没有任何意义。也许你的意思是它有一个功能的主体:

var myApp = function() { some code here };
var myCode = myApp();

在这种情况下,myApp被赋予一个函数表达式(这只是声明函数的几种方法之一)。它类似,但不完全相同:

function myApp() { some code here }
  

如果单词“require”作为一种匿名函数表达式,那么如何在后台实例化事物呢?这对于制作合适的图案非常重要,不是吗?

require('someModule)加载模块并从模块返回导出,该导出可以是任何Javascript数据类型。它不以任何方式充当匿名函数。 require()是一个实际的函数,你只是调用它并返回它的返回值。请记住,在Javascript中,您可以从函数返回任何数据类型,包括返回另一个函数(这是快递模块所做的)。

  

第一个例子的背景中发生了什么,是JavaScript / Node.js实例化/构建还是根本没有?

没有实例化或构建。它只是加载一个模块,运行其初始化代码并返回其导出。一些对象是由模块加载系统创建的,用于自己的内务处理,但模块本身只是初始化自己,然后决定它想要导出的内容。

  

这样做的人只是创造了糟糕的模式吗?我为什么要使用这种模式?

模块在node.js开发中非常有用,并且使用适当的模块设计被认为是很好的设计。良好的模块设计有许多很多优点,例如更容易的代码维护,更容易的代码测试,更容易的代码重用,更容易的代码共享,无需创建全局变量以共享代码等等。

  

如果没有实例化,为什么不呢?

模块决定要导出的内容。它可以在其初始化代码中创建对象的实例并将其导出。它可以导出一个工厂函数,在调用时创建一个对象实例。它可以直接导出构造函数,使调用者可以使用new来创建对象的实例。它可以导出一个只执行某些功能但不创建任何对象的实用程序功能。它只能导出数据。它可以导出具有多个属性的普通对象,这些属性具有各种可能的用途。可能性是无穷无尽的,它完全取决于模块的目的是什么,以及它希望与加载它的其他模块共享的内容。

答案 1 :(得分:2)

它只是将一个库或一个模块加载到您的脚本中。它没有实例化新对象。它只是使加载模块的功能等可用于当前脚本。这是我发现的一篇很好的文章, http://fredkschott.com/post/2014/06/require-and-the-module-system/ 我希望这有助于回答你的问题。

相关问题