<script src="a.js">script>
<script src="b.js">script>
<script src="util/wxbridge.js">script>
//A同学a.js
function onShow(){//xxxx}
//B同学b.js
function onShow(){//xxxx}
//重名概率太高
无法避免的全局变量污染
2002年左右,有人提出了命名空间模式的思路,用于解决全局变量被污染的问题
不过这种方式,毫无隐私可言,本质上就是全局对象,谁都可以来访问并且操作,一点都不安全
//A同学a.js
var A={
onShow(){},
onXXX(){},
//...
}
//B同学b.js
var B={
onShow(){}
}
//还是会重名,但比以前好一点
//比如 其他班A同学,由于合作,引入a.js、b.js
var A={
onShow(){}
}
模块太臃肿,不敢私自拆模块,又重名
拆模块带来的问题,私有属性乱,代码不灵活
多个文件之间存在依赖关系,需要保证加载顺序
//a.js
var a=''//重名,全局变量不安全
var A={
a:''//不重名,用起来比较乱
A1:{}
A2:{
B:{
a:''
}
}
}
console.log(A.A2.B.a);
(function(window, undefined){
// 代码...
})(window);
// a.js
var a = (function(cNum){
var aStr = 'a';
var aNum = cNum + 1;
return {
aStr: aStr,
aNum: aNum
};
})(cNum);
// c.js
var cNum = (function(){
var cNum = 0;
return cNum;
})();
//index.js
;(function(a, cNum){
console.log(a.aNum, cNum);
})(a, cNum)
//引入
<script src="./c.js">script>
<script src="./a.js">script>
<script src="./index.js">script>
// b.js
var b = (function(a){
var bStr = a.aStr + ' bb';
return {
bStr: bStr
};
})(a);
module export require
// a.js
module.exports = {
aStr: 'a'
};
// b.js
var a = require('./a');
exports.bStr = a.aStr + ' bb';
// index.js
var a = require('./a');
var b = require('./b');
console.log(a.aNum, b.bStr);
//module.js
function Module(id, parent) {
this.id = id; // 文件验重的表示,字符串形式的绝对路径
this.exports = {};
this.parent = parent;
if (parent && parent.children) {
parent.children.push(this);
}
this.filename = null;
this.loaded = false;
this.children = [];
}
module.exports = Module;
var module = new Module(filename, parent);
//在commonjs规范中每个模块都是一个Module实例
//require方法调用__load方法加载模块文件
//require的返回值是module.exports || {}
//exports = module.exports
//gulp
'use strict';
var util = require('util');
//...
function Gulp() {
//...
}
Gulp.prototype.task = Gulp.prototype.add;
Gulp.prototype.run = function() {
var tasks = arguments.length ? arguments : ['default'];
this.start.apply(this, tasks);
};
//...
var inst = new Gulp();
module.exports = inst;
var gulp = require('gulp')
AMD与Commonjs一样都是js模块化规范,是一套抽象的约束,2009年诞生
RequireJs,是AMD规范的具体实现(RequireJs诞生之后,推广过程中产生的AMD规范)
语法
//引入
require([module], callback);
//定义
define(id?, dependencies?, factory);
//引入require.js
<script src="/require.js" data-main="/main" async="async" defer>script>
//main.js
requirejs.config({
//...
paths: {
a: '/a.js',
c: '/c.js',
index: '/index.js'
}
});
require(['index'], function(index){
index();
});
//a.js
define('a', ['c'], function(c){
return {
aStr: 'aStr',
aNum: c.cNum + 1
}
});
//c.js
define('c', function(){
return {
cNum: 0
}
});
//index/js
define('index', ['a', 'c'], function(a, c){
return function(){
console.log(a.aNum, c.cNum);
}
});
// AMD
define(
['./a', './b'], // <- 前置声明,也就是在主体运行前就已经加载并运行了模块a和模块b
function (a, b) {
a.doSomething();
b.doSomething();
}
)
// CMD
define(function (require) {
var a = require('./a'); // <- 运行到此处才开始加载并运行模块a
a.doSomething();
var b = require('./b'); // <- 运行到此处才开始加载并运行模块b
b.doSomething();
})
// counter.js
exports.count = 0
setTimeout(function () {
console.log('500ms后自增的count的值为', ++exports.count, '')
}, 500)
// commonjs.js
const {count} = require('./counter')
setTimeout(function () {
console.log('commonjs:1000ms后读取count的值是', count)
}, 1000)
//es6.js
import {count} from './counter'
setTimeout(function () {
console.log('es6:1000ms后读取count的值是', count)
}, 1000)
➜ test node commonjs.js
500ms后自增的count的值为 1
commonjs:1000ms后读取count的值是 0
➜ test babel-node es6.js
500ms后自增的count的值为 1
es6:1000ms后读取count的值是 1