require是什么
require是nodejs提供的一种CommonJS规范的模块化引入api。每个.js文件都是一个模块,它们内部各自使用的变量名和函数名都互不冲突。一个模块提供module.exports对外暴露变量,使用require('id')引入其他模块输出的对象
模块化原理
因js语言作用域分为全局作用域与局部作用域,定义全局作用域的变量所有地方都可访问但变量名不可重复,局部作用域变量仅作用域块内可用。受自身作用域限制,没有一种机制可实现不同模块可使用相同的变量名,变量独立且互不影响。为了解决上述问题,Nodejs实现module编程使用闭包的思想,这样变量就成了函数的局部变量,从而实现了模块隔离。
示例: hello.js文件如下
var s = 'Hello';
var name = 'world';
console.log(s + ' ' + name + '!');
Node.js加载了hello.js后,它可以把代码包装一下,变成这样执行:
(function () {
// 读取的hello.js代码:
var s = 'Hello';
var name = 'world';
console.log(s + ' ' + name + '!');
// hello.js代码结束
})();
这样一来,原来的全局变量s现在变成了匿名函数内部的局部变量。如果Node.js继续加载其他模块,这些模块中定义的“全局”变量s也互不干扰。这就是Nodejs模块隔离思想。
模块的输出module.exports怎么实现?
// 先准备module对象:
var module = {
id: 'hello',
exports: {}
};
// 传入加载函数
var load = function (module) {
// 读取的hello.js代码:
function greet(name) {
console.log('Hello, ' + name + '!');
}
module.exports = greet;
// hello.js代码结束
return module.exports;
};
var exported = load(module);
// 保存module:
save(module, exported);
由于Node保存了所有导入的module,当我们用require()获取module时,Node找到对应的module,把这个module的exports变量返回,这样,另一个模块就顺利拿到了模块的输出
写法
如果要输出一个键值对象{},可以利用exports这个已存在的空对象{},并继续在上面添加新的键值;
如果要输出一个函数或数组,必须直接对module.exports对象赋值。
所以我们可以得出结论:直接对module.exports赋值,可以应对任何情况:
module.exports = {
foo: function () { return 'foo'; }
};
或者:
module.exports = function () { return 'foo'; };
最终,我们强烈建议使用module.exports = xxx的方式来输出模块变量,这样,你只需要记忆一种方法。