1. 模块系统
使用 node 编写应用程序主要就是使用:
- ECMAScript语言
- 核心模块:文件操作fs,http,url路径操作模块,path路径处理模块,od操作系统信息
- 第三方模块:art-template,必须通过npm下载才可以使用
- 自定义模块:自己创建的文件
2. CommonJS 模块规范
JavaScript本身是不支持模块化的。
模块化:
- 具有文件作用域
- 通信规则:加载 与 导出
但是在node 中的js 还有一个很重要的概念:模块系统。
- 模块作用域
- 使用 require 方法用来加载模块
- 使用 export 接口对象来导出模块中的成员
如果一个模块需要直接导出成员,而不是挂载的方式(即放到一个对象中),也就是说:不是返回一个 成员包括字符串,方法或者其他的对象,而是单纯地返回我想要的数组/字符串/方法,但是这样只能导出单个成员。而前面的办法可以导出多个成员则:
function add(x, y) {
return x + y
}
exports.add = add // 返回的是包含add方法的对象
module.exports = add // 返回的是add 方法
// 导出多个成员也可以这样做:
module.exports = {
add:function() {
},
str: 'hello'
}
3. 原理解析:
- 在node 中每一个模块内部,都有自己的module对象
- 在这个module对象中有一个成员:exports ,也是一个对象,并且这个对象为空
- 当然,这个module里面也有其他成员
- 并且默认在代码的最后有一句: return module.exports
- 我们看不见,因为这是在底层实现的
- 谁来require ,就得到这个module.exports对象
- 因此如果需要对外导出成员,只需要把导出的成员挂载到module.exports对象中
var module = {
exports:{
}
}
但是我们可以发现,每次要添加一个成员,都需要写一次 module.exports. 太过麻烦! 所以 node 为了简化操作,专门提供了一个变量: exports = module.exports,即exports 引用了module.exports
也就是说,在模块中还有这一句代码:var exports = module.exports。既然两者一致,则可以使用任意一个来导出成员。
// 前提:main.js require了下面这个模块
exports.a = 123
exports = {}
exports.foo = 'bar'
// 则:在main.js 里面console.log(fooExports) 会得到 123
// 从第二句代码开始,exports 指向了另一个对象,就不会再生效了
注意:exports 只是module.exports的引用,给exports重新赋值,和module.exports无关,因为指向了一个新的对象。一定要记住:最后return的是module.exports。 当我们给exports 重新赋值(第一次赋值是 var exports = module.exports,则二者指向同一个对象),exports 会指向一个新的对象。
- 在expotrts重新赋值之前的代码都能生效
- 只要module.exports 或者 exports 任意一个 重新赋值,二者的链接就会断开
例1:
exports.a = 123 // { a: 123 } // 在这里,module.exports.a和exports.a均为 123
exports = {} // 链接断开,重新为exports赋值了,对module.exports不起作用
exports.foo = 'bar' // 对module.exports不起作用
module.exports.b = 456 //{ a: 123, b: 456 }
例2:
module.exports = 'hello'
exports.foo = 'world'
// 得到的是 hello
//原因:给 module.exports 重新赋值,二者的链接也断开了
4. 练习题
练习1:
module.exports = { // 这次赋值断开了联系
foo: 'bar'
}
exports = module.exports // 重新建立联系
exports.foo = 'hello'
// 结果是: { foo: 'hello' }
练习2:
exports.foo = 'bar'
module.exports.a = 123
exports = {
a: 456
}
module.exports.foo = 'haha'
exports.c = 456
exports = module.exports
exports.a = 789
// 结果是: { foo: 'haha', a: 789 }
练习3:
exports.foo = 'bar'
module.exports.a = 123
exports = {
a: 456
}
module.exports.foo = 'haha'
exports.c = 456
exports = module.exports
exports.a = 789
module.exports = function() {
console.log('hello')
}
// 结果是: [Function (anonymous)]
3. 二者混用的情况
二者可以混用是以下情况,但是返回的是一个对象,而不是字符串:
module.exports.a = 'hello'
exports.b = 'world'
// { a: 'hello', b: 'world' }