`

javascript实现模块加载器

 
阅读更多

 

实现思路来自于网上资料,自己做了一些修改,仅供学习。

window.ISF = (function(win, doc) {
	Array.prototype.remove = function() {
        var items = arguments, 
            k = 0, 
            len = items.length, 
            item = null;
            
        for (; k < len; k++) {
            item = items[k];
            for (var i = 0, n = 0; i < this.length; i++) {
                if (this[i] != item) {
                    this[n++] = this[i];
                }
            }
            this.length = n;
        }
        return this;
    };
    
	var moduleCache = {},
		head = doc.head;
	
	function Mod(config){
		this.handlers = {}; 
		this.oneTimeHandlers = {}; 
		
		this.modName = config.modName;
		this.status =  config.status;
		this.export = config.export;
		
		
		this.on = function(type, handler){
			this.handlers[type] = this.handlers[type] || [];
			this.handlers[type].push(handler);
			return this;
		};
		
		this.off = function(type, handler){
			if(this.handlers[type]){
				this.handlers[type].remove(handler);
			}
			if(this.oneTimeHandlers[type]){
				this.oneTimeHandlers[type].remove(handler);
			}
			return this;
		};
		
		this.one = function(type, handler){
			this.oneTimeHandlers[type] = this.oneTimeHandlers[type] || [];
			this.oneTimeHandlers[type].push(handler);
			return this;
		}; 
		
		this.fire = function(){
			var eventResults = [],
				type = arguments[0],
				args = Array.prototype.slice.call(arguments, 1),
			   _handlers = this.handlers[type],
			   _oneTimeHandlers = this.oneTimeHandlers[type],
			   _oneTimeHandlersLen = _oneTimeHandlers.length;
			if(_handlers && _handlers.length > 0){
				for(var i = 0, len = _handlers.length; i < len; i++){
					eventResults.push(_handlers[i].apply(this, args));
				}
			}
			if(_oneTimeHandlers && _oneTimeHandlersLen> 0){
				for(var i = 0; i < _oneTimeHandlersLen; i++){
					eventResults.push(_oneTimeHandlers[i].apply(this, args));
					
				}
			}
			_oneTimeHandlers=[];
			return eventResults.length == 1 ? eventResults[0] : eventResults;
             
		};
		
	}
	var createScript = function(url,onload) {
		var _script = document.createElement('script');
		_script.type = 'text/javascript';
		_script.charset = 'utf-8';
		_script.async = true;
		_script.src = url;
		if(onload){
			_script.onload = function(){
				onload();
			};
		}
		var firstScript = document.getElementsByTagName('script')[0];
		if(firstScript){
			firstScript.parentNode.insertBefore(_script, firstScript);
		}else{
			 head.appendChild(_script);
		}
	};
	
	var loadMod = function(modName, callback) {
		 
		var mod = moduleCache[modName];
		if(mod){
			if(mod.status == 'loaded'){
				setTimeout(callback(mod.export), 0);
				
			}else{
				mod.one('loaded', callback);
			}
		}else{
			mod = moduleCache[modName] = new Mod({
				modName : modName,
				status : 'loading',
				export : null
			});
			mod.one('loaded', callback);
			createScript(modName + ".js");
		}
		
	};
	
	var saveModule = function(modName, params, factory){
		console.log('modName='+modName);
		var _export = (typeof factory == 'function') ? factory.apply(null, params) : factory;
		
		if(modName){
			var mod = moduleCache[modName];
			mod.status = 'loaded';
			mod.export = _export;
			mod.fire('loaded', mod.export);
		} 
		
	};
	
	var ISF = {
		
		loadModule : function(modName, factory, config) {
			config = config ||{};
			
			var requires = config.requires;

			if (requires && requires.length) {
				var params = [],
					depCount = 0;
				for (i = 0, len = requires.length; i < len; i++) {
					(function(i) {
						// 依赖加 1
						depCount++;

						loadMod(requires[i], function(param) {
							params[i] = param;
							depCount--;
							if (depCount == 0) {
								saveModule(modName, params, factory);
							}
						});
					})(i);
				}
			} else {
				saveModule(modName, [], factory);
			}
		},
		
		define : function(moduleName, factory, config) {
			this.loadModule(moduleName, factory, config);
		},
		
		use: function(modules, factory){
			this.loadModule(undefined, factory, {requires:modules});
		}

	};
	return ISF;

})(window, document);

 

测试:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title></title>
  <script src="ISF.js" type="text/javascript"></script>
</head>
<body>
</body>

<script type="text/javascript">
ISF.use(['util', 'math', 'num'], function (util, math, num) {
  num = math.getRadom() + '_' + num;
  num = util.formatNum(num);
  console.log(num);
});
</script>
</html>

 

ISF.define('math', function (num) {
  return {
    getRadom: function () {
      return parseInt(Math.random() * num);
    }
  };
}, {requires:['num']});

 

 ISF.define('num', function () {
   return 10;
 });

 

ISF.define('util', function () {
  return {
    formatNum: function (n) {
      if (n < 10) return '0' + n;
      return n;
    }
  };
});

 

分享到:
评论

相关推荐

    我的js模块加载器

    自己写的javascript模块加载器 里面有清楚的注释

    JavaScript模块加载器lodJS.zip

    JavaScript模块加载器,基于AMD。迄今为止,对AMD理解最好的实现。100%支持AMD规范,支持模块化开发,当定义好模块后,便可使用模块,无需维护依赖的模块,仅需写好依赖就可以了,lodJS会负责依赖注入。特性:模块化...

    JavaScript模块加载器DefineJS.zip

    DefineJS 是一个轻量级的异步模块定义 AMD 的实现,是一个 JavaScript 的模块加载器。 支持的浏览器包括: Google Chrome (latest) Opera (latest) Firefox 4 Safari 5 Internet Explorer 8 标签...

    RequireJS一个JavaScript文件和模块加载器

    RequireJS 是一个JavaScript库,它的主要功能是作为一个模块管理和加载器。在JavaScript的世界里,由于其天然的异步性质,管理多个脚本文件的依赖关系往往变得复杂且困难。RequireJS 为此提供了解决方案,它引入了...

    代码详解javascript模块加载器

    在给定的文件内容中,作者通过一系列的JavaScript代码示例,详细解析了如何创建一个简单的JavaScript模块加载器,并展示了如何定义模块、加载模块以及如何实现模块之间的依赖。 首先,作者定义了一个名为MyModules...

    用javascript实现的留言板模块

    【标题】"用JavaScript实现的留言板模块"是一个利用JavaScript编程语言构建的互动功能,它允许用户在网站上发表留言,包含表情、图片以及各种文字处理功能。JavaScript是一种轻量级的解释型编程语言,常用于网页和...

    javascript模块化

    Require.js是一种实现**AMD(Asynchronous Module Definition)**规范的JavaScript模块加载器。AMD规范允许模块异步加载,并且可以在定义模块时声明其依赖关系。这有助于减少页面加载时间和提高代码执行效率。 - **...

    JavaScript前端开发模块化教程_PPT.rar

    4. SystemJS:SystemJS 是一个运行时模块加载器,可以动态加载各种模块格式,包括ES6、CommonJS和AMD。它允许在浏览器和Node.js中运行,提供了更灵活的模块处理能力。 在JavaScript模块化开发中,我们还需要关注...

    JavaScript前端开发模块化教程_源代码.rar

    - **SystemJS**:一种运行时的模块加载器,支持多种模块格式。 4. **模块化实践** - **立即执行函数表达式(IIFE)**:常用于创建独立作用域,避免污染全局变量。 - **命名空间对象**:通过对象属性组织相关功能...

    ESL浏览器端的模块加载器支持延迟定义和AMD

    ESL作为企业级的JavaScript模块加载器,其对延迟定义和AMD的支持,使得它成为构建大型、高性能Web应用的理想选择。通过合理利用这些特性,开发者可以创建出更加高效、可扩展的应用程序,同时确保代码的可维护性和...

    requireJS模块加载器

    RequireJS 是一个JavaScript模块加载器。它非常适合在浏览器中使用, 它非常适合在浏览器中使用,但它也可以用在其他脚本环境, 就像 Rhino and Node. 使用RequireJS加载模块化脚本将提高代码的加载速度和质量。

    seajs js 模块加载器

    SeaJS 是一款专为Web端设计的JavaScript模块加载器,它的出现是为了解决JavaScript在浏览器环境中的组织和管理问题。随着Web应用的复杂度不断提升,JavaScript代码的组织和依赖管理变得至关重要,SeaJS 提供了一种...

    深入理解requireJS-实现一个简单的模块加载器

    要深入理解requireJS实现一个简单的模块加载器,我们首先需要了解模块化编程的重要性和它能解决的问题。模块化编程可以解决单文件变量命名冲突问题、前端多人协作问题、文件依赖问题以及按需加载。模块化编程通过将...

    Javascript模块化编程(Require.js)

    Require.js是JavaScript的一个模块加载器,它引入了AMD(Asynchronous Module Definition)规范,为JavaScript提供了异步加载模块的能力,尤其适合在浏览器环境中处理大量依赖关系。 在JavaScript中,早期的编程...

    WASMWebpack二进制模块加载器

    这里的“二进制模块加载器”特指用于处理WASM文件的Webpack加载器,它使得JavaScript能够与WebAssembly代码交互。 **描述分析:** 描述中提到的“WASM Webpack二进制模块加载器”,意味着我们需要关注如何在...

    JavaScript模块化编程七日

    - 学习配置Webpack,包括入口、输出、加载器(loaders)和插件(plugins)的设置。 - 实践使用Babel将ES6模块转换为CommonJS或UMD格式,以兼容不支持ES6模块的环境。 第四天:模块规范与实践 - 了解UMD(通用模块...

    javascript高级模块化require.js的具体使用方法

    Require.js是一种JavaScript模块加载器,它遵循AMD(异步模块定义)规范,这种规范允许你以异步的方式加载JavaScript模块。它非常小巧,压缩后的大小只有14KB,适合用于管理前端JavaScript模块的加载,能够有效地...

    javascript代码模块之20大实用源代码

    3. **ES6模块**:在浏览器环境中,我们可以使用`import`和`export`语句进行异步模块加载。这种方式更适合客户端,因为它支持按需加载,可以减少网络传输。 4. **UMD(Universal Module Definition)**:为了实现跨...

    JavaScript实现的相册

    在这个相册中,JavaScript可能会选择或创建DOM元素,如`&lt;img&gt;`标签来展示图片,并通过修改这些元素的属性(如`src`和`style`)来实现图片的加载和切换。 2. **事件监听**:相册通常会响应用户的点击或滑动事件,这...

    mini:一个小型的javascript的模块加载器

    总之,"mini"作为一个小型的JavaScript模块加载器,它为开发者提供了一种简单、高效的方式来管理和组织代码,是构建大型JavaScript应用的良好选择。通过学习和使用"mini",我们可以更好地掌握JavaScript的模块化编程...

Global site tag (gtag.js) - Google Analytics