exports
-
当一个模块被其他模块引用 会执行这个模块 并默认导出是一个空对象
// index.js const lib = require('./lib') console.log('引入的lib: ', lib) // 引入的lib: {} // lib.js console.log("hello, I'm lib") // 被引入时会执行该模块,打印hello, I'm lib -
exports指定模块的输出 (导出的是个对象 默认是{}) 可以在exports对象上,指定属性exports.key = value导出的是个json, 形如{ key: value }, key为json的key value是值,可以是基本类型, 也可以是对象或者函数// index.js const lib = require('./lib') console.log('引入的lib: ', lib) // 引入的lib: { hello: word } // lib.js exports.hello = 'word'- 可以导出多个属性
// index const lib = require('./lib') console.log('引入的lib:', lib) // 引入的lib { hello: 'word', sum: [Function], info: { name: 'test', version: '1.1.1' } } // lib exports.hello = 'word' exports.sum = function (a, b) { return a + b } exports.info = { name: 'test', version: '1.1.1' }
-
当前模块的
exports的引用 和 其他模块require的结果, 是否是同一个引用?
是同一个引用// index const lib = './lib' lib.addtional = 'test' // 在index模块 去修改lib模块 打印可以看到会影响到lib模块 // lib exports.hello = 'word' console.log(exports) // { hello: 'word' } setTimout(() => { console.log(exports) // { hello: 'word', addtional: 'test' } }, 2000)
module
module结构// module对象默认是一个 Module实例 // lib-module console.log(module) /* Module { id: '', // filename(好像不是哦 因为还有一个filename的属性) path: '', dirname exports: {}, // 1.默认是一个空对象, 可以通过exports.key挂载属性; 2.当定义了module.exports时, 该属性就指向module.exports parent: Module {}, // 父级module, 引入这个模块的模块(在这里是main中引入了lib-module, 所以parent: 指向的是main的module) filename: '', loaded: false, children: [], // [ [Circular] ] paths: [] } */module.exports属性- 当没有定义
module.exports时, 则module.exports指向的是exports对象。// main const lib_module = require('./lib_module') console.log(lib_module) // {hello: 'word'} // lib_module exports.hello = 'word' console.log(module) // Module {..., exports: { hello: word }, ... }如果在
main.js中, 给引入的lib_module添加属性,lib_module.js的exports和module.exports都会添加到这个属性// main const lib_module = require('./lib_module') lib_module.addtional = 'test' // lib_module exports.hello = 'word' console.log(module) // Module {..., exports: { hello: word }, ... } setTimout(() => { console.log(exports) // { hello: 'word', addtional: 'test' } console.log(module) // Module {..., exports: { hello: 'word', addtional: 'test' }, ... } }) - 定义了
module.exports, 则module.exports指向的是定义的module.exports。// main const lib_module = require('./lib_module') // lib_module exports.hello = 'word' module.exports = { lastName: 'Chen', fistName: 'YiXun' } console.log(exports) // { hello: 'word' } console.log(module) // Module {..., { lastName: 'Chen', fistName: 'YiXun' }, ...} module.exports导出一个函数, 给引入的lib_module模块添加属性// main const lib_module = require('./lib_module') console.log(lib_module) // [Function: sum] lib_module.addtional = 'test' console.log(lib_module) // [Function: sum] { addtional: 'test' } // lib_module module.exports = function sum (a, b) { return a + b } setTimout(() => { console.log(module) // Module { ..., exports: [Function: sum] { addtional: 'test' }, ... } })- 定义了多个
module.exports, 后定义的会覆盖之前定义的// main const lib_module = require('./lib_module') console.log(lib_module) // { test: '覆盖成功' } // lib_module module.exports = function sum (a, b) { return a + b } module.exports = { test: '覆盖成功!' } module.exports导出可以是任意值, 包含基本类型,module.exports导出的是什么, require到的就是什么// main let lib_module = require('./lib_module') console.log(lib_module) // 'aa' // lib_module module.exports = 'aa'
- 当没有定义
module.exports指定的模块输出和require的模块引用, 是同一个引用吗
是同一个引用// main const lib_module = require('./lib_module') lib_module.addtional = 'test' // lib_module exports.hello = 'word' module.exports = { lastName: 'Chen', fistName: 'YiXun' } setTimout(() => { console.log(module) // Module { ..., exports: { lastName: 'Chen', fistName: 'YiXun' }, ... } console.log(exports) // { hello: 'word' } })
注意: 不管是
exports, 还是module.exports, require到的和导出的对象都是同一个引用 修改了引入的模块的对象的属性, 模块就会对应该变;但是直接修改指向是不生效的: 这点不难理解, 因为修改属性lib_module.key = ..., 此时lib_module与require同一个引用;而一旦执行lib_module = ...时,lib_module与require就不是同一个引用了lib_module.test = '添加属性成功', 则lib_module.js里会给module的exports对象加test属性; 而lib_module = {test: 'change' }, 是不会将lib_module.js的module.exports 修改为{ test: 'change' }