我刚刚浏览了 nodejs 源代码,注意到不同模块导出方式之间的差异。例如,某些模块导出具有原型(prototype)继承样式的对象:
Thing = function () {
constructor stuff
}
Thing.prototype.jump () {
jump stuff
}
exports = Thing
其他模块会将函数直接附加到导出:
exports.spectacles = function () {
spectacle stuff
}
在我看来,他们将实现相似的目标,但他们显然不同。我相信第一个示例描述的是类似于类的内容,而第二个示例只是提供了可用的静态方法。
这两种方法之间的根本区别是什么?如何正确描述它们以及一种方法相对于另一种方法的优点/缺点是什么?
尝试从另一个角度来看:需要您的模块的模块。
Node 中的每个文件都是一个模块。每个模块都有一个全局变量,module
,以及它的属性,exports
。无论您在 exports
属性上放置什么,都将作为模块的导出提供。
原始
即。 bool 值、数字或字符串都可以:
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 = {},那么如果我们简单地附加到它,我们可以向它添加 props:
因此,当 Node 第一次获取您的模块(文件)时,它是一个 {}。我们可以简单地附加 Prop 。
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); // <== {}
希望对您有所帮助。