关于module.exports 和 exports

1. 模块系统

使用 node 编写应用程序主要就是使用:

  • ECMAScript语言
  • 核心模块:文件操作fs,http,url路径操作模块,path路径处理模块,od操作系统信息
  • 第三方模块:art-template,必须通过npm下载才可以使用
  • 自定义模块:自己创建的文件

2. CommonJS 模块规范

JavaScript本身是不支持模块化的。

模块化:

  1. 具有文件作用域
  2. 通信规则:加载 与 导出

但是在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' }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值