我只是浏览nodejs源,并注意到不同模块导出方式之间的差异。例如,某些模块使用原型继承样式导出对象:
Thing = function () {
constructor stuff
}
Thing.prototype.jump () {
jump stuff
}
exports = Thing
其他模块将函数直接附加到导出:
exports.spectacles = function () {
spectacle stuff
}
对我来说,似乎他们会实现类似的目标,但他们显然是不同的。我相信第一个例子描述的类似于一个类,而第二个例子只是提供静态方法。
这两种方法之间的根本区别是什么,它们如何正确描述以及哪一方面的优点/缺点是什么?
答案 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投票结果。这个问题非常主观。