【问题标题】:Differences between nodejs modules and their exports [closed]nodejs模块及其导出之间的差异[关闭]
【发布时间】:2014-07-08 16:16:54
【问题描述】:

我刚刚浏览了 nodejs 源代码,并注意到不同模块的导出方式之间存在差异。例如,某些模块导出具有原型继承样式的对象:

Thing = function () {
  constructor stuff
}

Thing.prototype.jump () {
  jump stuff
}

exports = Thing

其他模块会将函数直接附加到导出:

exports.spectacles = function () {
  spectacle stuff
}

在我看来,他们会实现相似的目标,但显然是不同的。我相信第一个示例描述了类之类的东西,而第二个示例只是提供了可用的静态方法。

这两种方法之间的根本区别是什么,如何正确描述它们以及其中一种方法相对于另一种方法的优点/缺点是什么?

【问题讨论】:

    标签: node.js oop static node-modules


    【解决方案1】:

    尝试从另一个角度看待这个问题:需要你的模块的模块。

    Node 中的每个文件都是一个模块。每个模块都有一个全局变量module,以及它的属性exports。无论您在 exports 属性上添加什么,都可以作为模块的导出。

    原语

    即。布尔值、数字或字符串都可以:

    module.exports = 3;
    

    当您需要该文件时,您将获得“3”。

    var myModule  = require('./my-module');
    console.log(myModule); // <== 3
    

    但是由于 JavaScript 中的一切都是对象,所以你可以调用方法,甚至是原始的 prop:

    console.log(myModule.toString()); // <== "3"
    

    功能

    您还可以导出函数。

    module.exports = function() {
        console.log('3 more');
    };
    

    那个导出将是一个函数:

    var myModule  = require('./my-module');
    myModule(); // <== '3 more'
    

    当然,函数也是对象,所以你也有方法可以尝试。

    console.log(myModule.toString());
    // You get: 'function (){\n    console.log(\'3 more\');\n    }'
    

    对象

    然后你可以导出一个包含一些东西的对象:

    module.exports = {
        prop: 3,
        method: function() {
            console.log('Not 3 this time.');
        }
    };
    

    当您需要此模块时,您将拥有该对象 - 具有属性 prop 和方法 method 的对象。

    var myModule  = require('./my-module');
    console.log(myModule.prop); // <== 3
    myModule.method();          // <== 'Not 3 this time'
    

    所以你明白模式了吗?无论你在 module.exports 中放入什么,你在另一端都会得到什么。正如我所说的,这是一个观点问题。

    默认

    即使您不导出任何内容(即需要一个空文件),您也可以导出。

    需要一个空文件(它必须存在

    var myModule  = require('./my-module');
    console.log(myModule); // <== {}
    

    这告诉您默认导出是一个空对象。


    这就是有趣的地方。

    如果 module.exports = {} 默认情况下,那么如果我们简单地附加到它,我们可以给它添加道具:

    因此,当 Node 首次获取您的模块(文件)时,它是一个 {}。我们可以简单地为其附加道具。

    module.exports.prop = 3;
    module.exports.method = function() { console.log('I am out of ideas for placeholders, I should use kitten');}
    

    为什么没有module 关键字也能工作?

    现在,为什么在没有模块关键字的情况下它可以工作? IE。只是:

    exports.prop = 3;
    exports.method = function() {};
    

    因为当 Node.js 开始处理您的文件时,它会将 export 别名为 module.exports。 但要小心,您可以覆盖它!

    这是什么意思?就好像你在文件的开头写了var exports = module.exports

    所以你可以只使用exports 语法,但我不想这样做。为什么?因为你可能会犯错误并覆盖exports var。而且你会更加小心 module.exports。 (还有其他原因,这个是我最先了解的,也是我记得最清楚的。)

    示例 1:

    exports.prop = false;
    
    // later in module
    module.exports = myObj; // see? overriden. 
    

    示例 2:

    var exports = {}; // see? Overridden default module.exports.
    exports.prop = 4;
    
    exports.method = function(){
        console.log('3 more');
    };
    

    所以当你以后需要这个时:

    var myModule  = require('./my-module');
    console.log(myModule); // <== {}
    

    我希望这会有所帮助。

    【讨论】:

    • 感谢 Zlatko,非常全面。
    【解决方案2】:

    您指出的差异主要是基于风味的。这与人们喜欢如何构建他们的对象非常相关。

    Javascript 有很多不同的方式来构建对象,这里是另一个例子:

    exports.stuff = {
       f1: function() ...
       foobar: function() ...
    }
    

    例如,我更喜欢用函数包装所有内容以强制使用严格和模拟静态变量:

    (function() {
      "use strict";
       var staticVariable; 
    
       function MyObject() {
         ...
       };
    
       exports.MyObject = MyObject;
    })();
    

    +1 接近投票。这个问题很主观。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-12
      • 2015-04-02
      相关资源
      最近更新 更多