//Global污染,命名污染 function foo(){}
//命名空间 NameSpace模式 var Module= { foo: function(){}, } Module.foo(); //减小Global上变量数量,但仍不安全
//匿名闭包 IIFE模式 var Module = (function(global){ var _private = $("body"); var foo = function(){console.log(_private)} return { foo: foo } })($) Module.foo(); Module._private; // undefined
Node 应用由模块组成,采用 CommonJS 模块规范。每一个文件就是一个模块,有本身的做用域。在一个文件里面定义的变量、函数、类,都是私有的,对其余文件不可见。在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块须要提早编译打包处理。javascript
//add.js module.exports.add = function(a, b) { return a + b; }; //main.js const add = require("./add.js").add; module.exports.square_difference = function(a, b) { return add(a, b) * decrease(a, b); };
(Asynchronous Module Definition 异步加载模块定义 )
用于浏览器端,异步加载,依赖前置(提早加载)其核心接口是:define(id?, dependencies?, factory)html
//require.js var a = require("./a"); a.doSomething(); var b = require("./b") b.doSomething(); // AMD recommended style define(["a", "b"], function(a, b){ a.doSomething(); b.doSomething(); })
AMD规范以后又容许输出模块兼容CommonJS规范和依赖后置,代码和下面的cmd同样。前端
(Common Module Definition 通用模块定义 )
用于浏览器端,异步加载,依赖就近。java
//sea.js define(function(require, exports, module){ var a = require("a"); a.doSomething(); var b = require("b"); b.doSomething(); // 依赖就近,延迟执行 })
相似于兼容 CommonJS 和 AMD 的语法糖webpack
(function (root, factory) { if (typeof define === 'function' && define.amd) {// AMD define(['b'], function (b) { return (root.returnExportsGlobal = factory(b)); }); } else if (typeof module === 'object' && module.exports) {// CommonJS. (Node) module.exports = factory(require('b')); } else {// Browser globals root.returnExportsGlobal = factory(root.b); } }(typeof self !== 'undefined' ? self : this, function (b) { return {}; }));
import XXX from './a.js' export function a() {} //export default function() {}
在 CommonJS 规范中,当遇到 require() 语句时,会执行 require 模块中的代码,并缓存执行的结果,当下次再次加载时不会重复执行,而是直接取缓存的结果。
ES6 中,import 优先于模块内的其余内容执行。export与其对应的值是动态绑定关系,实时取到模块内部的值。git
参考资料:
前端模块化详解
模块系统
探索 JavaScript 中的依赖管理及循环依赖github