上QQ阅读APP看书,第一时间看更新
2.1.3 导入
在CommonJS中使用require进行模块导入。如:
// calculator.js module.exports = { add: function(a, b) {return a + b;} }; // index.js const calculator = require('./calculator.js'); const sum = calculator.add(2, 3); console.log(sum); // 5
我们在index.js中导入了calculator模块,并调用了它的add函数。
当我们require一个模块时会有两种情况:
·require的模块是第一次被加载。这时会首先执行该模块,然后导出内容。
·require的模块曾被加载过。这时该模块的代码不会再次执行,而是直接导出上次执行后得到的结果。
请看下面的例子:
// calculator.js console.log('running calculator.js'); module.exports = { name: 'calculator', add: function(a, b) { return a + b; } }; // index.js const add = require('./calculator.js').add; const sum = add(2, 3); console.log('sum:', sum); const moduleName = require('./calculator.js').name; console.log('end');
控制台的输出结果如下:
running calculator.js sum: 5 end
从结果可以看到,尽管我们有两个地方require了calculator.js,但其内部代码只执行了一遍。
我们前面提到,模块会有一个module对象用来存放其信息,这个对象中有一个属性loaded用于记录该模块是否被加载过。它的值默认为false,当模块第一次被加载和执行过后会置为true,后面再次加载时检查到module.loaded为true,则不会再次执行模块代码。
有时我们加载一个模块,不需要获取其导出的内容,只是想要通过执行它而产生某种作用,比如把它的接口挂在全局对象上,此时直接使用require即可。
require('./task.js');
另外,require函数可以接收表达式,借助这个特性我们可以动态地指定模块加载路径。
const moduleNames = ['foo.js', 'bar.js']; moduleNames.forEach(name => { require('./' + name); });