export、export default和exports、module.exports的区别和用法
在ES6和Nodejs中,一个js文件就是一个模块,模块里面定义的所有变量都是私有的,外部无法直接获取;
现在我们可以在另外一个模块中,使用ES6对应import命令,来加载main.js,获取导出的变量
1.2. export default命令
export default指定模块的默认导出,即外部模块无需知道导出的变量名,也可以导入该变量;
外部模块在导入时,可以为该函数指定任意合法变量名;
export default的本质是导出一个名为default的变量,比如上述例子中,实质上是将名为funx的函数,
命名为default进行导出。
注意:一个模块中只能有一个默认导出,所以使用import导入时,后面无需加{ };
更多详细用法请移步:https://es6.ruanyifeng.com/#docs/module
2. Nodejs中的用法
上文提到过,Nodejs的模块机制是基于CommonJs语法规范的。CommonJS规范规定,每个模块内部,module
变量代表当前模块。
这个变量是一个对象,它的exports
属性(即module.exports
)是对外的接口。加载某个模块,其实是加载该模块的module.exports
属性。
2.1 module.exports
在Nodejs中执行下面的utils.js文件:
输出结果为:
可以看到module.exports默认是一个空对象,因为该模块尚未导出任何变量。
由于module对象的exports属性是该模块的对外接口,因此要想导出相关变量时,只需对module.exports进行赋值即可。
2.2 exports
为了方便,Node还为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。
再来改写utils.js的代码如下:
在Nodejs中执行utils.js,输出的结果为:
从输出结果可以看出确实如此。
因此,在对外输出模块接口时,也可以向exports对象添加变量和方法。
注意,不能直接将exports变量指向一个值,因为这样等于切断了exports
与module.exports
的联系。
现在我们可以使用CommonJs的require命令,在其它模块中导入utils.js,require的本质是引入module.exports的值。
最后输出的结果只有name和age两个属性,是因为,加载某个模块,其实是加载该模块的module.exports
属性,
而utils.js中的module.exports已经被重新赋值了,引用指向了另外一个对象,而exports的引用还是指向原来的空对象,
对exports添加属性并没有影响到module.exports的值。所以上面utils.js中的写法是有问题的。
如果你觉得,exports
与module.exports
之间的区别很难分清,一个简单的处理方法,就是放弃使用exports
,只使用module.exports
。