模块作用域的好处
每个js文件都有自己的一个module对象,它里面存储了和当前模块有关的信息;
这样防止全局变量污染的问题,如:两个JS文件都有命名一样的变量,变量只会在自己的js文件的作用域下才会有作用。
CommentJS
module
每个js文件中module的结构如下
例如
Module {
id: '.',
exports: {},
parent: null,
filename: '/Users/mahk/Desktop/mymaclearn/webpack-learn/test.js',
loaded: false,
children: [],
paths:
[ '/Users/mahk/Desktop/mymaclearn/webpack-learn/node_modules',
'/Users/mahk/Desktop/mymaclearn/node_modules',
'/Users/mahk/Desktop/node_modules',
'/Users/mahk/node_modules',
'/Users/node_modules',
'/node_modules' ]
}
module.exports
每个module对象下都会有一个exports,将模块内的成员去共享出去给外面用
而外面通过require()就可以导入被共享的成员
例如
a文件
const demo = {
name: 'mahk'
}
const demoFunction = () => {
console.log('hello ' + demo.name)
}
module.exports = {demoFunction};
b文件
const {demo, demoFunction} = require('./a.js');
console.log(demo); // undefined
demoFunction(); // hello mahk
exports
由于 module.exports 单词写起来比较复杂,为了简化向外共享成员的代码,Node提供了 exports 对象。
其实和 module.exports 的使用一模一样,也是把模块内的成员共享出去,但是module.exports是export的老大,也就是说,最终最终共享的结果,还是以 module.exports 指向的对象为准。什么意思呢,就是当出现export共享了变量a,但是module.exports共享了变量b,最终能共享的只有b
ES6规范
es6中有多种写法
1、export定义导出的变量或函数,再用import进行引用
a文件
export const name = mahk;
const mahkSex = 'boy';
export {mahkSex as sex}; // 换个名字导出
b文件
import {name, sex} form './a.js';
console.log(name, sex); // mahk boy
2、export default导出,每个文件只能使用一次
a文件
export default {
name: 'mahk',
}
b文件
import myName from './a.js';
console.log(myName); // {name: 'mahk'};
3、通配符导入
a文件
export const name = 'mahk';
export const sex = 'box';
export const age = 25;
b文件
import * as person from './a.js';
console.log(person); // {name: 'mahk', sex: 'box', age: 25};
import 和 require的区别
1、require是AMD规范引入方式,而import是ES6的一个语法标准,如果要兼容浏览器的话必须转化成 ES5 的语法;
2、require是运行时调用,理论上放在代码中哪一处都可以,import是编译时调用,一般放在文件开头;
3、require是赋值过程,import是解构过程;