在模块化开发过程中经常遇到模块的导出导入。涉及到 require 、module.exports、exports这些关键词。下面来谈谈他们的关系和区别。
首先谈谈他们的规范
require: node 和 es6 都支持的引入;
module.exports / exports: 只有 node 支持的导出;
(export / import : 只有es6 支持的导出引入)。
module
和exports
是Node.js
给每个js文件内置的两个对象。可以通过console.log(module)
和console.log(exports)
打印出来。
console.log(exports);//输出:{}
console.log(module);//输出:Module {..., exports: {}, ...} (注:...代表省略了其他一些属性)
module.exports
和exports
一开始都是一个空对象{}
,实际上,这两个对象指向同一块内存。这也就是说在不去改变它们指向的内存地址的前提下module.exports
和exports
是等价的。
require
引入的对象本质上是module.exports
。这就产生了一个问题,当 module.exports
和exports
指向的不是同一块内存时,exports
的内容就会失效。
区别
require导出的内容是module.exports的指向的内存块内容,并不是exports的。
区分他们之间的区别就是 exports 只是 module.exports的引用,辅助后者添加内容用的。
用法举例
返回全局共享的变量或者方法。
moudel.exports
var app = {
name: 'app',
version: '1.0.0',
sayName: function(name){
console.log(this.name);
}
}
module.exports = app;
var app = require('./app.js');
app.sayName('hello');//hello
exports
var func1 = function() {
console.log("func1");
};
var func2 = function() {
console.log("func2");
};
exports.function1 = func1;
exports.function2 = func2;
var functions = require("./functions");
functions.function1();
functions.function2();
返回一个构造函数
var CLASS = function(args){
this.args = args;
}
module.exports = CLASS;
var CLASS = require('./CLASS.js');
varc = new CLASS('arguments');
返回一个实例对象:
//CLASS.js
var CLASS = function(){
this.name = "class";
}
CLASS .prototype.func = function(){
alert(this.name);
}
module.exports = new CLASS();
var c = require('./CLASS.js');
c.func();//"class"
面试题
总结
本来在node中
this===exports===moudule.exports
若同时写两个导出,则会出现以下情况
如果不改变exports和moudel.exports的内存指向(即不对它们直接赋值),那么定义的属性和方法都会被导出。若对exports和moudel.exports同时赋值,那么只会导出moudel.exports的。若对exports赋了值且moudel.exports未直接赋值,那么this上定义的和用moudel.exports上定义的属性正常导出,exports被切断,不会被导出。
(注意区别是直接赋值还是定义属性)