【问题标题】:var express = require('express'); var app = express(), What is express()?? is it a method or a constructor? Where does it come fromvar express = require('express'); var app = express(), 什么是 express()??它是方法还是构造函数?它从何而来
【发布时间】:2015-02-20 08:53:59
【问题描述】:
var express = require('express'); 
var app = express();

这就是我们创建快速应用程序的方式。但是这个'express()'是什么?它是方法还是构造函数?哪里来的??

【问题讨论】:

  • require('express') 返回一个函数引用。使用 express() 调用该函数。 app 是 express() 返回的对象。
  • 其实是instantiates Express,并给它赋值app变量。
  • 我认为这是我对 javascript 的理解的问题,你能告诉我如何在不显式输入 'express.express()' 的情况下调用存储在变量 'express' 中的函数的引用
  • 我建议你在nodejs中编写一个示例模块。然后你可以找出为什么你应该这样做。它比我们为您解释的要好。

标签: javascript node.js express


【解决方案1】:

是方法还是构造函数?

都不是;这是一个函数,虽然如果你说的是“方法”,我认为没有人会为难你。

方法是附加到对象的函数。在 JavaScript 中,方法只是主要是您通过对象属性引用的函数。 (更新:从 ES2015 开始,如果您使用方法语法来创建它们,它们更多,因为它们可以访问super。)

构造函数,在 JavaScript 中,是您通过 new 运算符调用的函数。尽管其他函数可能会创建东西,但我们通常不会将它们称为“构造函数”以避免混淆。有时它们可​​能是“创建者”或“构建者”函数。

它来自哪里?

ExpressJS 是一个NodeJS moduleexpress 是模块的名称,也是我们通常赋予变量的名称,我们在代码中用于引用其主要功能,例如您引用的内容。 NodeJS 提供了require function,它的工作是加载模块并允许你访问它们的导出。 (您没有调用变量express,您可以使用var foo = require('express'); 并改用foo,但惯例是您将使用模块的名称,或者仅使用模块的一部分,使用模块文档定义的该部分的名称。)

express 的默认导出有点不寻常,因为它是一个函数,它的属性也是函数(方法)。这在 JavaScript 中是完全有效的¹,但在其他一些语言中却相当不寻常。这就是为什么您可以通过express() 创建一个Application 对象,但也可以使用express.static(/*...*/) 来设置服务静态文件。


¹事实上,这是完全正常的。默认情况下,函数有几个标准方法:例如callapplytoString

【讨论】:

  • 发帖人还问了var app = express();,你能评论一下吗?它似乎引起了我的问题(请参阅我的 SO 问题here)。 app 每次都是不同的实例吗?
  • @edddd - 一些模块返回一个函数,其他模块返回一个带有属性/方法的对象。从技术上讲,一个模块可以返回任何东西,包括一个数字或字符串。
  • @edddd - JavaScript 中的函数(以及方法)是对象,因此它们可以具有属性,并且这些属性可以引用函数:function example() { console.log("example was called"); } example.static = function static() { console.log("example.static was called"); }; example(); example.static();jsfiddle.net/tjcrowder/y459gpdz
  • @T.J.Crowder 知道了,谢谢,我从来没有想过这个问题
  • @r3za - express.js 中的这一行:mixin(app, proto, false);。这会将proto 中的所有内容复制到appprotoapplication.js 的默认导出。在application.js 中,还有另一个app(这次是一个对象var app = exports = module.exports = {};),代码将use 和其他函数分配给它。所以proto 中的express.jsapp 中的application.js
【解决方案2】:

您将使用 Node 的 require 函数来使用 express 模块。 require 类似于其他语言中的 import 或 include 等关键字。 require 将包的名称作为字符串参数并返回一个包。返回的对象没有什么特别之处——它通常是一个对象,但它可以是一个函数、一个字符串或一个数字。

var express = require('express'); 

=> 需要 Express 模块,就像您需要其他模块一样,并将其放入变量中。

var app = express(); 

=> 调用 express 函数“express()”并将新的 Express 应用程序放入 app 变量中(以启动新的 Express 应用程序)。 这就像您正在创建一个类的对象。其中“express()”就像类,app 是新创建的对象。

通过查看下面的 express 代码,您可以了解里面真正发生的事情。

文件 1:index.js

'use strict';

module.exports = require('./lib/express');

文件 2:lib/express.js

'use strict';

var EventEmitter = require('events').EventEmitter;
var mixin = require('merge-descriptors');
var proto = require('./application');
var Route = require('./router/route');
var Router = require('./router');
var req = require('./request');
var res = require('./response');

/**
 * Expose `createApplication()`.
 */

exports = module.exports = createApplication;

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

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

  app.request = { __proto__: req, app: app };
  app.response = { __proto__: res, app: app };
  app.init();
  return app;
}
exports.application = proto;
exports.request = req;
exports.response = res;    
exports.Route = Route;
exports.Router = Router;
});

require 的工作原理

当你在 node 中调用 require('some_module') 时会发生什么:

  1. 如果当前文件夹节点中存在名为 some_module.js 的文件,则会加载该文件,否则:

  2. Node 在当前文件夹中查找 node_modules 文件夹,其中包含 some_module 文件夹。

  3. 如果没有找到,它会上一个文件夹并重复步骤2

这个循环一直重复,直到节点到达文件系统的根文件夹,此时它将检查所有全局模块文件夹(例如 Mac OS 上的 /usr/local/node_modules),如果它仍然找不到 some_module 它会抛出异常。

【讨论】:

  • 谢谢,查看代码帮助我很好地掌握了这个想法。
【解决方案3】:

古帖。我认为最初的发布者对为什么调用模块 express 导出的函数的语法是

感到困惑
var app = express() 

而不是

var app = express.express()

澄清一下:require() 函数不会创建对该“模块”的引用。没有对模块的引用。只有对模块导出的事物的引用。

require('xxx.js'),其中 .js 扩展名可以省略,返回该 xxx.js 文件导出的任何内容。如果那个 xxx.js 文件导出一个对象, require('xxx.js') 返回一个对象;如果一个函数被导出, require('xxx.js') 返回一个函数;如果导出单个字符串,则 require('xxx.js') 返回一个字符串...

如果您检查文件 express.js 的源代码,您会看到它导出了一个函数。所以在

var express = require('express')

第一个 express 分配了模块 express 导出的任何内容,在这种情况下,它恰好是一个函数。 express 是一个函数,而不是对模块的引用。因此,在第二行,您只需调用该函数:

var app = express()

希望这会有所帮助!

【讨论】:

  • 啊我明白了,如果var foobar = require('express'),那么var app = foobar()?
  • 是的。你可以随便命名。按照惯例,您将 express.js 导出的函数命名为“express”。当您调用该函数时,它会返回一个对象。按照惯例,您将该对象命名为“app”。通过遵循这些约定,其他程序员可以更快地消化您的代码。
  • 这让我发疯了。谢谢!
  • express 也出口其他东西,正如 Shersha 评论的那样。 module.exports = 创建应用程序;所以函数createApplication可以直接访问。
【解决方案4】:

让我通过一个例子来回答这个问题。 创建 2 个 javascript 文件。 play1.js 和 express.js

//express.js
function createApplication(){
   var app = 'app';
    return app;
  }
module.exports = createApplication;
//keep in mind that we are not doing module.exports = {createApplication}

现在在 play1.js 文件中导入 express.js

//play1.js
  var express = require('./express);
   var app = express();
 // this will call createApplication function as app is referencing to it.
   console.log(app); // "app"

【讨论】:

    【解决方案5】:

    每当您导入类似的模块时

    const express = require('express')
    

    express 是一个分配有函数或对象或变量的模块。 看看/lib/express

    您可以在 express 模块中以 express() 的形式访问函数 createApplication,因为该函数是直接分配给模块的

    exports = module.exports = createApplication;

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

    所以你可以访问函数 createApplication 只需调用 express() 作为函数

    现在,当您查看 express 库的其他部分时,您还可以看到一堆附加到 export 特殊对象的其他对象。

    /**
     * Expose the prototypes.
     */
    
    exports.application = proto;
    exports.request = req;
    exports.response = res;
    
    /**
     * Expose constructors.
     */
    
    exports.Route = Route;
    exports.Router = Router;
    
     // other exports
    

    分配给导出特殊对象的这些对象或函数可以使用 express 作为对象从导入部分访问。

    快递。{姓名}

    express.Route
    express.Router etc
    

    最后你只是导出了一堆方法或对象,这些方法或对象附加到 express js 文件中的 module.export 特殊对象

    要了解更多关于 module.export 特殊对象的信息,请转到 here

    【讨论】:

      【解决方案6】:
      1-  var express = require('express');
      

      第一行需要 express 包 .js 文件,并且“需要”它只返回使用 (module.exports) 在 js 文件中导出的内容。 所以我们只有指向这个函数的指针。

      2- var app = express();
      

      在第二行,我们使用'app'作为pleaceholder来接收express()函数的输出,它是一个对象,我们可以在我们的代码中使用它(通过访问他的方法和属性,就像任何其他类一样)

      换句话说,我们使用从“express.js”文件中导入的“express()”函数生成的“app”对象。

      注意 1) 当然我们可以使用任何名称来代替 'app' ,但是当您遵循大多数开发人员用来命名此包的名称时,这是一个很好的做法,这样在您工作时更容易理解您的代码专业团队。

      注意 2) 在 ES6 之后,我们使用 'const' 而不是 'var' 。

      【讨论】:

        【解决方案7】:

        当我们的应用程序需要模块时,我们在 node js 中编写的简单内容

        const modue_need1=require('module_name'); 
        const modue_need2=require('module_name2'); 
        const modue_need3=require('module_name3'); 
        const modue_need4=require('module_name4'); 
        const modue_need....=require('module_name.....');
        

        所以对于每一个模块,我们都需要写这么大的代码,而现在为了减少这些冗长的代码和时间片,我们该怎么做呢?我们需要像 Express js 这样的 node js 框架 这将克服这些问题意味着“少写,多做” 我们只使用这两条线,我们应用程序的所有需求(模块)都将是它们的应用程序内对象,我们可以在需要时使用它,因此不需要为每个模块调用 require。 “少写,多做”

        const express=require('express');
        const app=express();
        console.log(app);
        

        【讨论】:

          猜你喜欢
          • 2019-02-27
          • 2018-04-18
          • 2017-11-03
          • 1970-01-01
          • 2023-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-12
          相关资源
          最近更新 更多