binperson / blog

personal blog 😍
Apache License 2.0
0 stars 0 forks source link

CommonJS规范 #4

Open binperson opened 6 years ago

binperson commented 6 years ago

参考 CommonJS规范

概述

//example.js
var x = 5;
var addX = function (value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

//加载模块
var example = require('./example.js');
console.log(example.x); // 5
console.log(example.addX(1)); // 6
binperson commented 6 years ago

module对象

module.exports属性

module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。

exports变量

为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。

var exports = module.exports;

造成的结果是,在对外输出模块接口时,可以向exports对象添加方法。

exports.area = function (r) {
  return Math.PI * r * r;
};

exports.circumference = function (r) {
  return 2 * Math.PI * r;
};

不能直接将exports变量指向一个值,因为这样等于切断了exports与module.exports的联系。

exports = function(x) {console.log(x)};
module.exports = function (x){ console.log(x);};

如果模块输出的是一个函数,那就不能定义在exports对象上面,而要定义在module.exports变量上面。

// a.js
module.exports = function () {
  console.log("hello world")
}
//b.js
require('./a.js')()
binperson commented 6 years ago

require命令

require('./example.js');
require('./example.js').message = "hello";
require('./example.js').message
// "hello"

连续三次使用require命令,加载同一个模块。第二次加载的时候,为输出的对象添加了一个message属性。但是第三次加载的时候,这个message属性依然存在,这就证明require命令并没有重新加载模块文件,而是输出了缓存。

// 删除指定模块的缓存
delete require.cache[moduleName];

// 删除所有模块的缓存
Object.keys(require.cache).forEach(function(key) {
  delete require.cache[key];
})
binperson commented 6 years ago

模块的加载机制

CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值