Posted in Javascript onMarch 27, 2012
lang.js库提供了包和类的定义、类的继承与混合(mixin)、函数重载等功能,基本可满足大多数面向对象设计的需求。同时支持基于链式的定义方式,让库在使用时更加规范和便捷。下面首先通过简单的例子演示了lang.js的基本功能,之后给出了lang.js的源码及注释。
一.功能介绍
“lang”作为框架的全局定义,其中包括了四个方法:
lang.Package(string name) //用于定义包(默认会暴露到全局)
lang.Class(string name[, object config], object classBody) //用于定义类
lang.Object(string name | object body) //用于定义支持重载函数的普通对象
lang.Function(string name | object body) //用于定义重载函数
var lang = (function(){ /*********************************** Javascript面向对象扩展库(lang.js v1.0) By: X!ao_f QQ: 120000512 Mail: xiao_f.mail#163.com ************************************/ var customToString = function(){ return '[' + this.Type.type + ' ' + this.Type.name + ']'; } //支持重载的方法定义 var createMethod = (function(){ //创建一个代理函数 var createMethodProxy = function(context, name){ //当调用重载的函数时,首先会执行该函数分析传入的参数,进行匹配和转发 var method = function(){ //在第一次调用时初始化,将映射信息缓存 if(!method.__initialized__){ initializeMethod(method); } //将参数类型拼接成函数签名 var signature; if(arguments.length){ var list = []; for(var i=0; i<arguments.length; i++){ var typename; var argument = arguments[i]; if(argument === undefined || argument === null){ typename = 'object'; }else if(argument instanceof Array){ typename = 'array'; }else if(argument instanceof Date){ typename = 'date'; }else{ typename = typeof argument; if(typename == 'object'){ if('Class' in argument){ typename = argument.Class.Type.name; }else if('nodeType' in argument){ typename = 'element'; } } } list.push(typename); } signature = list.join(','); }else{ signature = ''; } //如果常规缓存中存在匹配的签名,直接调用 if(method.__overloads__[signature]){ return method.__overloads__[signature].apply(this, arguments); }else{ //缓存中不存在时,尝试利用正则进行模糊匹配 //首先判断模糊匹配缓存中是否存在记录,如存在直接调用 if(method.__overloadsCache__[signature]){ return method.__overloadsCache__[signature].apply(this, arguments); } //循环匹配 for(var i=0; i<method.__overloadsRegExp__.length; i++){ //如果匹配成功,将映射关系存入模糊匹配缓存,同时调用并返回 if(method.__overloadsRegExp__[i].regexp.test(signature)){ method.__overloadsCache__[signature] = method.__overloadsRegExp__[i].fn; return method.__overloadsRegExp__[i].fn.apply(this, arguments); } } //如果依然无法找到对应的函数,判断是否存在默认函数 if(method.__overloads__['default']){ return method.__overloads__['default'].apply(this, arguments); }else if(method.__overloads__['']){ return method.__overloads__[''].apply(this, arguments); }else{ alert('Error: '+method.Type.name+'('+signature+') is undefined.'); } } }; //内置对象 method.__context__ = context; method.__functions__ = {}; method.toString = customToString; //自描述信息 method.Type = { name: name, Method: method, type: 'method' }; return method; } //初始化 var initializeMethod = function(method){ //基础签名缓存 method.__overloads__ = {}; //模糊匹配正则缓存 method.__overloadsRegExp__ = []; //模糊匹配结果缓存 method.__overloadsCache__ = {}; //例举所有定义的函数 for(var signature in method.__functions__){ var fn = method.__functions__[signature]; var params = signature.substring(signature.indexOf('(') + 1, signature.length - 1); var pure = !/[\*\+\?\{]/.test(params); //如果不存在通配符直接保存到基础签名缓存 if(pure){ method.__overloads__[params] = fn; }else{ //生成模糊匹配正则 var regexp = '^' + params .replace(/([\w\.]+)(\{.*?\})?/g, '($1(,|$))$2') .replace(/\./g, '\\.') .replace(/((\()var(\())/g, '$2\\w+$3') .replace(/,\(/g, '(') + '$'; method.__overloadsRegExp__.push({ regexp: new RegExp(regexp), fn: fn }); } } method.__initialized__ = true; } //返回外部的定义函数 return function(signature, fn, comp){ //如果传入的为一个对象,视为定义匿名方法 if(typeof signature == 'object'){ var context = {}; var method; for(var key in signature){ method = createMethod.call(context, 'anonymous'+key, signature[key]); } return method; } signature = signature.replace(/\s+/g, ''); var index = signature.indexOf('('); var name = index > -1 ? signature.substring(0, signature.indexOf('(')) : signature; var context = this; var method = context[name]; //上下文中不存在函数定义,视为第一次定义 if(method === undefined){ context[name] = method = createMethodProxy(context, name); }else if(!method.Type || method.Type.type!='method'){ //上下文存在的函数是原生函数,将这个函数作为默认函数存入列表 var temp = method; context[name] = method = createMethodProxy(context, name); method.__functions__[name + '()'] = temp; }else{ //如果上下文不同,创建新的重载方法并将已经存在的函数复制,这里主要解决类继承中子类与父类冲突的问题 //如果上下文相同,直接将初始化标记设为false,待下次调用时重新初始化 if(method.__context__ !== context){ var temp = method; context[name] = method = createMethodProxy(context); for(var sign in temp.__functions__){ method.__functions__[sign] = temp.__functions__[sign]; } }else{ method.__initialized__ = false; } } //将本次定义的函数添加到函数列表 //先入为主策略 if(comp){ if(fn.__functions__){ for(var key in fn.__functions__){ if(key in method.__functions__){ method.__functions__[key].__overridden__ = fn; }else{ method.__functions__[key] = fn; } } }else{ if(signature in method.__functions__){ method.__functions__[signature].__overridden__ = fn; }else{ method.__functions__[signature] = fn; } } }else{ //后入为主策略 if(fn.__functions__){ for(var key in fn.__functions__){ if(key in method.__functions__){ fn.__functions__[key].__overridden__ = method; } method.__functions__[key] = fn.__functions__[key]; } }else{ if(signature in method.__functions__){ fn.__overridden__ = method; } method.__functions__[signature] = fn; } } if(this.Type && this.Type.type == 'package'){ return this; }else{ return method; } }; })(); //类定义函数 var createClass = (function(){ var slice = Array.prototype.slice; var emptyFn = function(){}; var createClass = function(name){ return function(){ this[name].apply(this, slice.call(arguments, 0)); }; } //用于调用被重写函数 var baseCaller = function(){ if(arguments.length){ var args = slice.call(arguments, 0); return baseCaller.caller.__overridden__.apply(this, args); }else{ return baseCaller.caller.__overridden__.call(this); } } //用于调用自身重载构造函数 var selfCaller = function(){ if(arguments.length){ var args = slice.call(arguments, 0); return selfCaller.caller.__self__.apply(this, args); }else{ return selfCaller.caller.__self__.call(this); } } var filter = {prototype:true, Type:true}; //快速浅拷贝 function clone(a){ var fn = function(){}; fn.prototype = a; return new fn; } //对象复制,替换存在的(后入为主) function replace(base, self){ for(var key in self){ if(!(key in filter)){ if(typeof self[key] == 'function'){ //如果子类函数包含重载签名或父类函数已经重载 if(key.indexOf('(') > -1 || (base[key] && base[key].__functions__)){ createMethod.call(base, key, self[key]); }else{ //常规函数定义 if(key in base){ //记录重写信息 self[key].__overridden__ = base[key]; } base[key] = self[key]; } }else{ base[key] = self[key]; } } } } //对象复制,只取补集(先入为主) function complement(self, base){ for(var key in base){ if(!(key in filter)){ if(typeof base[key] == 'function'){ if(key.indexOf('(') > -1 || (self[key] && self[key].__functions__)){ createMethod.call(self, key, base[key], true); }else{ if(key in self){ //记录重写信息 self[key].__overridden__ = base[key]; }else{ self[key] = base[key]; } } }else if(!(key in self)){ self[key] = base[key]; } } } } return function(){ //处理参数 if(this.Type && this.Type.type == 'package'){ if(arguments.length == 2){ var name = arguments[0]; var body = arguments[1]; }else{ var name = arguments[0]; var config = arguments[1]; var body = arguments[2]; } }else{ if(arguments.length == 1){ var name = 'Anonymous'; var body = arguments[0]; }else{ var name = 'Anonymous'; var config = arguments[0]; var body = arguments[1]; } } //创建类的基础函数 var clazz = createClass(name); //获取父类信息 var baseClass; if(config && config.extend){ baseClass = config.extend; } //如果传入的主体为函数,取其返回值 if(typeof body == 'function'){ body = body(clazz); } //处理静态成员 if(body.Static){ complement(clazz, body.Static); delete body.Static; body = body.Public||body; }else{ body = body.Public||body; } //处理继承 if(baseClass){ //通过快速浅拷贝复制父类成员 clazz.prototype = clone(baseClass.prototype); //继承静态成员 complement(clazz, baseClass); //继承类成员 complement(clazz.prototype, body); }else{ //不存在继承 clazz.prototype = {}; complement(clazz.prototype, body); } //处理混合 if(config && config.mixin){ var mixin = config.mixin; if(mixin instanceof Array){ for(var i=0; i<mixin.length; i++){ replace(clazz.prototype, mixin[i]); } }else{ replace(clazz.prototype, mixin); } } //添加内置函数 clazz.prototype.base = baseCaller; clazz.prototype.self = selfCaller; clazz.prototype.constructor = clazz; clazz.prototype.toString = customToString; clazz.toString = customToString; clazz.prototype.Class = clazz; if(clazz.prototype[name]){ var constructor = clazz.prototype[name]; if(constructor.__functions__){ for(var key in constructor.__functions__){ //存在重载时,添加自身引用,用于通过this.self调用重载构造函数 constructor.__functions__[key].__self__ = constructor; //存在继承时,将父类的构造函数作为被重写的函数,配置给当前类的构造函数 //用于通过base调用父类构造函数 if(baseClass){ constructor.__functions__[key].__overridden__ = baseClass.prototype[baseClass.Type.shortName]; } } }else if(baseClass){ clazz.prototype[name].__overridden__ = baseClass.prototype[baseClass.Type.shortName]; } }else{ clazz.prototype[name] = emptyFn; } //类型自描述信息 //如果当前上下文是一个包,将类添加到包中 if(this.Type && this.Type.type == 'package'){ clazz.Type = { type:'class', name: this.Type.name+'.'+name, shortName: name, Package: this, Class: clazz, baseClass: baseClass } clazz.prototype.Type = { type: 'object', name: this.Type.name+'.'+name } //将类添加到包 this[name] = clazz; //调用静态构造函数 if(name in clazz){ clazz[name].call(clazz); } //返回this用于链式调用 return this; }else{ //上下文不是包则直接返回 clazz.Type = { type:'class', name: name, shortName: name, Class: clazz, baseClass: baseClass } clazz.prototype.Type = { type: 'object', name: name, baseClass: baseClass } if(name in clazz){ clazz[name].call(clazz); } return clazz; } }; })(); //用于创建支持重载的普通对象 var createObject = function(objects, config){ var target; if(this.Type && this.Type.type == 'package'){ target = this; }else{ target = {}; } if(typeof objects == 'string'){ target = this[objects] = {}; objects = config; }else if(typeof objects == 'function'){ objects = objects(); } for(var key in objects){ if(typeof objects[key] == 'function' && (key.indexOf('(') > -1 || typeof target[key] == 'function')){ createMethod.call(target, key, objects[key]); }else{ target[key] = objects[key]; } } if(this.Type && this.Type.type == 'package'){ return this; }else{ return target; } }; //用于创建包 var createPackage = (function(){ var root = this; return function(package){ var name = []; var path = package.split('.'); var parent = root; for(var i=0; i<path.length; i++){ name.push(path[i]); if(parent[path[i]]){ parent = parent[path[i]]; }else{ var pack = { Class: createClass, Object: createObject, Function: createMethod, Package: createPackage, toString: customToString }; pack.Type = { type: 'package', Package: pack, name: name.join('.') } parent = parent[path[i]] = pack; } } return parent; } })(); //默认将Package暴露 window.Package = createPackage; return { Package: createPackage, Class: createClass, Function: createMethod, Object: createObject }; })();
结束语:
到这里,lang.js的应用和原理就介绍完毕了,该库在主流浏览器中均已测试通过,
如果想使用lang.js,可以在这里免费下载,如发现什么问题,或有好的建议可以反馈给我。
Javascript面向对象扩展库代码分享
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@