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-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 -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
结束语:
到这里,lang.js的应用和原理就介绍完毕了,该库在主流浏览器中均已测试通过,
如果想使用lang.js,可以在这里免费下载,如发现什么问题,或有好的建议可以反馈给我。