- 类充当自己方法的模块
- 类方法相互独立是因为每个方法都被定义成独立的原型对象的属性
- 类成为模块是因为对象是模块
函数中声明的局部变量和嵌套函数都是函数私有的,可以使用立即调用的函数表达式实现某种模块化,实现细节和辅助函数隐藏在包装函数中,只把模块中的公共 API 作为函数的值返回
const BitSet = (function() {
const BITS = new Uint8Array([1, 2, 4, 8, 16, 32, 64, 128]);
const MASKS = new Uint8Array([~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128]);
return class BitSet extends AbstractWritableSet {
};
}());
const stats = (function() {
const sum = (x, y) => x + y;
const square = x => x * x;
function mean(data) {
return data.reduce(sum) / data.length;
}
function stddev(data) {
let m = mean(data);
return Math.sqrt(
data.map(x => x - m)
.map(square)
.reduce(sum)
/ (data.length - 1)
);
}
return {
mean,
stddev
};
})();
console.log(stats.mean([1, 3, 5, 7, 9]));
console.log(stats.stddev([1, 3, 5, 7, 9]));
10.1.1 基于闭包的模块自动化
- 读取指定目录中的所有文件。
- 将每个文件的内容包装在一个IIFE中,并创建一个变量来保存模块的导出对象。
- 创建一个函数来加载模块并返回它的导出对象。
- 假设文件中定义了函数,并创建了一个函数来调用这些函数并返回它们的返回值。这里假设函数名已经提前知道(在真实场景中,你需要解析文件内容来提取函数名)。
- 拼接所有文件的代码,包括加载模块和调用函数的函数。
- 将拼接后的内容写入一个输出文件。
const fs = require('fs');
const path = require('path');
function readDir(dirPath) {
return fs.readdirSync(dirPath).map(file => path.join(dirPath, file));
}
function wrapInIIFE(content) {
return `(function() {
${content}
return { exports: exports };
})();`;
}
function parseFile(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const moduleName = path.basename(filePath, path.extname(filePath));
const wrappedContent = wrapInIIFE(content);
const exportsVar = `exports_${moduleName}`;
const loadModule = `function load_${moduleName}() {
return ${wrappedContent}.exports;
}`;
const callModuleFunction = (functionName) => `function call_${moduleName}_${functionName}() {
const module = load_${moduleName}();
if (typeof module.${functionName} === 'function') {
return module.${functionName}.apply(module, arguments);
}
throw new Error('Function ${functionName} does not exist in module ${moduleName}');
}`;
let result = loadModule + '\n';
const functionNames = ['function1', 'function2'];
for (const functionName of functionNames) {
result += callModuleFunction(functionName) + '\n';
}
return result;
}
function concatenateFiles(dirPath) {
const filePaths = readDir(dirPath);
let concatenatedContent = '';
for (const filePath of filePaths) {
concatenatedContent += parseFile(filePath) + '\n';
}
return concatenatedContent;
}
function buildModuleBundle(dirPath, outputFilePath) {
const bundleContent = concatenateFiles(dirPath);
fs.writeFileSync(outputFilePath, bundleContent);
console.log(`Bundle created at ${outputFilePath}`);
}
const dirPath = './modules';
const outputFilePath = './bundle.js';
buildModuleBundle(dirPath, outputFilePath);