从头开始写框架(二):孕育框架的种子_下

终于来到最后一节了!

今天我们会把我们的种子模块完成,之后就可以开始扩展我们的框架了!是不是开始有些兴奋了呢?

先来回顾一下之前的内容:

我们搞定了命名空间、多库共存机制、模块扩展机制。

恩,跟我们开始定好的目标只差一小步了。现在我们来完成它

首先,先来用模块扩展机制为我们的命名空间添加方法,我们来简单的添加三个方法:多库共存、toString、toNumber

function(module, exports, require){

	var _Cvm = window.Cvm , _$ = window.$;
     //在exports上面注册方法,来为命名空间扩展功能
	exports.reName=function(deep){ //冲突处理机制

		window.$ = _$;

		if(deep){
 
        window.Cvm = _Cvm; 
 
    	};

    	return Cvm;

	};

	exports.toString=function(val){ //toString
		return val.toString();
	}

	exports.toNumber=function(str){ //toNumber
		var n = Number(str);
		return !isNaN(n) ? n : "";
	}

}

  

OK,那么我们定义好了一个模块,之后在工厂方法中将模块的方法返回给命名空间:

return (function(modules){// 用来注册和生产用户调用的模块和方法,参数为模块的集合

		var moduleDepot = {} //缓存区

		function require(moduleId){

			if(moduleDepot[moduleId])
				return moduleDepot[moduleId];  //直接调用缓存

			var module = {
				exports:{},
				moduleId:moduleId,
				loaded:false
			};

			modules[moduleId].call(module.exports, module, module.exports, require); //获得模块

			moduleDepot[moduleId] = module; //添加缓存

			module.loaded=true;

			return module.exports //返回模块

		};

		return require(0); // 返回第0个模块

  

测试一下:

<script src="../jquery-1.8.3.min.js"></script>
<script src="Cvm.js"></script>
<script>
//先引入一个命名空间同样为$的JQ

var _ = $.reName();

var a = _.toString(123);
var b = _.toNumber("456");


console.log(typeof a) //string
console.log(typeof b) //number
</script>

  

OK,到现在为止,基本上我们的种子模块就完成了!

只差一个问题:我们只把第0个模块注册到了命名空间上,但是我们不可能把所有功能都写在同一个模块里,因为这样的话就无法多人去编写框架了,而且对以后的维护升级都是一个巨大的屏障。

我们需要一个中介者来完善模块的扩展机制:

function(module, exports, require){

	var _ = require(1); //将扩展功能的模块请求过来

	var extend = _.extend; //获得扩展的方法

	var p = {}; // 中介者

	extend(p , require(2)); // 为中介者注册方法
	
	module.exports = p; //最终返回中介者
},
//*  0-end  *//
//
//
//*  1-start  *//
function(module, exports){ // 扩展模块

	exports.extend = function(to , from){
		var keys = Object.keys(from);
		var i = keys.length;

		while(i--){
			to[keys[i]] = from[keys[i]];
		}
		return to;
	}

},
//*  1-end  *//
//
//
//*  2-start  *//
function(module, exports, require){ //多库共存模块
	var _Cvm = window.Cvm , _$ = window.$;

	exports.reName=function(deep){ //多库共存

		window.$ = _$;

		if(deep){
 
        window.Cvm = _Cvm; 
 
    	};

    	return Cvm;

	};
},
//*  2-end  *//

  

使用中介者p来扩展功能,然后返回这个中介者。此时这个中介者已经拥有所有扩展后的功能了,所以即使我们在种子模块里并没有请求多库共存的模块,但因为它已经被扩展给了中介者,所以最后我们还是可以得到这个模块的所有功能。

这样,我们的种子模块就彻底宣告完成了。你可以在此基础上,任意的扩展你的命名空间,也可以很方便的完成模块之间的依赖引用。

完整代码:

!function(global , target){

	if(typeof global !== 'undefined'){

		global.Cvm = global.$ = target();

	}else{

		throw new Error("Cvm requires a window with a document")

	}

}(typeof window !== 'undefined'? window : this , function(){ //工厂是一个函数

	return (function(modules){// 用来注册和生产用户调用的模块和方法,参数为模块的集合

		var moduleDepot = {} //缓存区

		function require(moduleId){

			if(moduleDepot[moduleId])
				return moduleDepot[moduleId].exports;  //直接调用缓存

			var module = {
				exports:{},
				moduleId:moduleId,
				loaded:false
			};

			modules[moduleId].call(module.exports, module, module.exports, require); //获得模块

			moduleDepot[moduleId] = module; //添加缓存

			module.loaded=true;

			return module.exports //返回模块

		};

		return require(0);

})([
//*  0-start  *//
function(module, exports, require){

	var _ = require(1);

	var extend = _.extend;

	var p = {}; // 中介者

	extend(p , require(2));
	
	module.exports = p;
},
//*  0-end  *//
//
//
//*  1-start  *//
function(module, exports){

	exports.extend = function(to , from){
		var keys = Object.keys(from);
		var i = keys.length;

		while(i--){
			to[keys[i]] = from[keys[i]];
		}
		return to;
	}

},
//*  1-end  *//
//
//
//*  2-start  *//
function(module, exports, require){
	var _Cvm = window.Cvm , _$ = window.$;

	exports.reName=function(deep){ //多库共存

		window.$ = _$;

		if(deep){
 
        window.Cvm = _Cvm; 
 
    	};

    	return Cvm;

	};
},
//*  2-end  *//
])
})

  

最后说两句:

模块扩展机制的好处是:方便多人协作完成一个框架的编写。

因为编写一个大型、功能完备的框架毕竟不是一个容易的事情,需要很多人很长时间去完成的,所以模块扩展机制的好处在此就有很大的发挥空间。

而模块的编写就像拼装玩具,把各个独立的功能拼接在一起,就变成了一个完整而强大的功能。

实际上,编写框架就是这样一个过程:在工作中不断积累业务需求与解决方法,并且不停的抽象你的代码。当你的代码累积到一定的数量级后,自然而然的就会开始编写框架。

至于之后的功能,我们以后再来展开!

原文地址:https://www.cnblogs.com/BlueQ/p/5066430.html