nodejs模块与其导出之间的差异

时间:2014-07-08 04:11:20

标签: node.js oop static node-modules

我只是浏览nodejs源,并注意到不同模块导出方式之间的差异。例如,某些模块使用原型继承样式导出对象:

Thing = function () {
  constructor stuff
}

Thing.prototype.jump () {
  jump stuff
}

exports = Thing

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

exports.spectacles = function () {
  spectacle stuff
}

对我来说,似乎他们会实现类似的目标,但他们显然是不同的。我相信第一个例子描述的类似于一个类,而第二个例子只是提供静态方法。

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

2 个答案:

答案 0 :(得分:4)

尝试从另一个角度查看:需要模块的模块。

Node中的每个文件都是一个模块。每个模块都有一个全局var module及其属性exports。无论您在exports属性上放置什么,都可以作为模块的导出。

原始

IE中。布尔值,数字或字符串将起作用:

module.exports = 3;

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

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

但是因为JavaScript中的所有内容都是一个对象,所以你甚至可以调用方法甚至是一个原始的道具:

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关键字呢?

现在,为什么没有module关键字呢? IE浏览器。只是:

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

因为当Node.js开始处理你的文件时,它会导出到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); // <== {}

我希望这会有所帮助。

答案 1 :(得分:3)

您指出的差异主要是基于味道的。这与人们喜欢如何构建对象密切相关。

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

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

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

(function() {
  "use strict";
   var staticVariable; 

   function MyObject() {
     ...
   };

   exports.MyObject = MyObject;
})();

+1投票结果。这个问题非常主观。