目录
模块
CommonJs规范中规定了每一个文件都是一个模块。使用require导入的文件会形成一个属于自身的模块作用域,这样就不会在进行变量以及函数声明时会污染全局作用域。所有的变量和函数都只有模块自身能访问,对外不可见的。
举例:
// foo.js
var name = 'foo';
// bar.js
var name = 'bar';
require('./foo.js');
console.log(name); // bar
在bar.js中通过require函数加载foo.js。运行之后输出的结果是‘bar’,这就说明了foo.js中的变量声明并不会影响bar.js。每个文件都拥有自己的作用域。
导出
导出是一个模块对外暴露自身的唯一方式。在CommonJs中,通过module.exports可以导出模块中的内容。
举例:
module.exports = {
name: 'foo'
}
CommonJs模块内部会有一个module对象用于存放当前模块的信息,可以理解为在每个模块的最开始中定义了以下对象:
var module = {};
// ...
module.exports = {};
CommonJs也支持另一种导出方式:exports。
exports.name = 'foo'
在实现上,这段代码与上面的module.exports没有不同,其内在机制是将exports指向了module.exports。可以简单的理解为CommonJs在每个模块的开头默认添加了以下代码:
var module = {
exports: {}
}
var exports = module.exports;
因此,为export.name赋值相当于在module.exports对象上添加了一个name属性。
Ⅰ、也很容易看出exports与module.exports只是指向同一个对象。所以对exports进行赋值操作,使其指向新的对象,就会失效了。
ingenious:由上面可以知道 即使require 导出后也无法改变模块对象!!
举例:
exports = {
name: 'foo'
}
此时name属性并不会被导出。
Ⅱ、另外这两个方法,并不能一起运用。因为使用module.exports赋值就相当于使其指向新的对象。之前的exports赋值都会失效。
导入
CommonJs使用require函数进行导入操作。
举例:
// foo.js
module.exports = {
sayname: function () {
console.log('foo');
}
};
// bar.js
var sayname = require('./foo.js').sayname;
sayname(); // foo
在bar.js中导入了foo.js,并调用了它的sayname函数。
当require一个模块时会有两种情况:
- 模块是第一