# CommonJS中的导出

// cal.js中导出一个工具
module.exports = {
  name: 'cal',
  add: function(a, b) {
    return a + b;
  }
}
// 为了誊写利便,可以像下面简写
exports.name = 'cal';
exports.add = function(a, b) {
  return a + b;
}

上面两段代码,在实现效果上没有任何的差别.

其内在机制是将exports指向了module.exports,而moudle.exports在初始化时是一个空工具.我们可以简朴的理解为,CommonJS在每个模块的首部默认添加了以下代码:

var module = {
  exports: {}
}

var exports = module.exports

因此,为exports.add赋值,相当于在module.exports工具上添加了一个属性

# 注重:

在使用exports时要注重一个问题,即不要直接给exports赋值,否则导致其失效,如:

exports = {
  add: function(a, b) {
    return a + b;
  }
}

上面代码中,由于对exports进行了赋值操作,使其指向了一个新的工具,module.exports却仍然是原来的空工具,因此add属性并不会被导出,例如下面这个代码:

var module = {
  exports: {}
}

var exports = module.exports

console.log(exports === module.exports) // true
exports = {
  add: function(a, b) {
    return a + b
  }
}
console.log(exports === module.exports) // false  注重这个地方是false

# 注重:

另一个需要注重的问题,module.exports和exports不要混用

exports.add = function(a, b) {
  return a + b
}

module.exports = {
  name: 'cal'
}

上面代码中的module.exports指向了另一个工具,导致之前的add属性被丢失,以是最后导出只有name属性

# 注重:

在module.exports和exports后面的代码依旧会执行,但不建议这样写

# CommonJS中的导入

使用require导入模块时,有下面两种情形:

1.require的模块是第一次被加载.这时会首先执行该模块,然后导出内容

2.require的模块曾被加载过.这时该模块的代码不会再次执行,而是直接导出上次执行后的效果

,

联博接口

www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

,

例如:

// cal.js
console.log('cal.js')
module.exports = {
  name: '我是乔峰',
  add: function(a, b) {
    return a + b
  }
}
// index.js
// 第一次require
const add = require('./cal').add
console.log(add(1, 2))


// 第二次require
const name = require('./cal').name
console.log(name)

此时的效果如下:

从效果上可以看出,只管我们require两次,但其内部代码只会执行一遍.

其原理大致如下:

在模块中,有一个module工具用来存储信息,这个工具中有一个属性loaded用于纪录该模块是否被加载过.它的默认值是false,当模块第一次被加载和执行过后会酿成true

若是后面再次加载时,检测到loaded为true,则不会次再执行模块代码

# 注重:

有时我们加载一个模块,不需要获取其导出的内容,只是想要通过执行它而发生某种作用,好比把它的接口挂载到全局工具上,此时直接使用require即可

require('./task.js')

# 注重:

另外,require可以吸收表达式,可以动态加载指定的模块

const moduleNames = ['foo.js', 'bar.js']
moduleNames.forEach(name => {
  require('./' + name)
})