1 common.js规范
我们编写了一个hello.js文件,这个hello.js文件就是一个模块,模块的名字就是文件名(去掉.js后缀),所以hello.js文件就是名为hello的模块。
graph LR
hello.js-->hello
'use strict';
var s = 'Hello';
function greet(name) {
console.log(s + ', ' + name + '!');
}
module.exports = greet;
1.1 结论
++在模块中对外输出变量++
module.exprts = varible;
++引入其他模块的对象用++
var foo = require('other_module');
1.2 深入理解模块原理
==js中申请全局变量==
var s = 'global';
当然我们知道大量的使用全局变量会造成变量污染,我们尽量的取不同的巨长的名字取避免这种问题,但是有时候还是会出现变量冲突的情况
node就可以在不同模块来实现变量相同但是相互不影响的
--demo: hello.js--
var s = 'Hello';
var name = 'world';
console.log(s + ' ' + name + '!');
--然后node加载hello.js,我们包装一下--
(function(){
var s = 'Hello';
var name = 'world';
console.log(s + ' ' + name + '!');
})();
==这样一来,原来的全局变量s现在变成了匿名函数内部的局部变量。如果Node.js继续加载其他模块,这些模块中定义的“全局”变量s也互不干扰。==
所以,Node利用JavaScript的函数式编程的特性,轻而易举地实现了模块的隔离。
1.3 实现module.exports
node事先准备一个对象module:
// 准备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);
可见,变量module是Node在加载js文件前准备的一个变量,并将其传入加载函数,我们在hello.js中可以直接使用变量module原因就在于它实际上是函数的一个参数:
==module.exports = greet;==
通过把参数module传递给load()函数,hello.js就顺利地把一个变量传递给了Node执行环境,Node会把module变量保存到某个地方。
由于Node保存了所有导入的module,当我们用require()获取module时,Node找到对应的module,把这个module的exports变量返回,这样,另一个模块就顺利拿到了模块的输出:
==var greet = require('./hello');==
以上是Node实现JavaScript模块的一个简单的原理介绍。
1.3 输出变量的方法 module.exports&exports
方法一:对module.exports赋值:
// hello.js
function hello() {
console.log('Hello, world!');
}
function greet(name) {
console.log('Hello, ' + name + '!');
}
module.exports = {
hello: hello,
greet: greet
};
方法二:直接使用exports:
// hello.js
function hello() {
console.log('Hello, world!');
}
function greet(name) {
console.log('Hello, ' + name + '!');
}
function hello() {
console.log('Hello, world!');
}
exports.hello = hello;
exports.greet = greet;
==但是你不可以直接对exports赋值:==
// 代码可以执行,但是模块并没有输出任何变量:
exports = {
hello: hello,
greet: greet
};
也就是说,默认情况下,Node准备的exports变量和module.exports变量实际上是同一个变量,并且初始化为空对象{},于是,我们可以写:
exports.foo = function () { return 'foo'; };
exports.bar = function () { return 'bar'; };
也可以写:
module.exports.foo = function () { return 'foo'; };
module.exports.bar = function () { return 'bar'; };
换句话说,Node默认给你准备了一个空对象{},这样你可以直接往里面加东西。
但是,如果我们要输出的是一个函数或数组,那么,只能给module.exports赋值:
module.exports = function () { return 'foo'; };