js中基于Ext的反射

2 篇文章 0 订阅
本文探讨了如何在JavaScript中,特别是在Ext库的基础上,实现反射功能。通过分享的Ext.Reflect.js源码和Ext.Reflect.test.js测试代码,作者展示了如何利用反射进行对象属性和方法的检查与操作,这对于增强代码的动态性和可维护性具有重要意义。
摘要由CSDN通过智能技术生成
不好意思,这个Ext.Reflect实际上是一个假反射,哈哈(*^_^*)……
实现的方式其实是,读源码中的注释信息,解析文件里面注释信息,组织成为一个描述类信息的对象。在使用的时候,大家不用太担心每次进行“反射”的时候都要去服务器端请求,大大降低了界面的响应。在这个地方,我做了一点小小的处理,凡是请求的过的“反射”,我已经存到Ext.Reflect.classes里面去了,第二次“反射”的时候,直接去取就可以了。

当然啦,既然假反射,肯定很假啦,只能“反射”Ext标准注释的js类,哈哈!那我自己写的Ajax和Ext.Reflect能不能反射呢,大家看了我的源码也就知道了,当然肯定也是不可以的啦!

我一直在琢磨,在js里面能不能实现一个真反射呢,吼吼~~有待研究……有志之士可以给点力哦

以下是Ext.Reflect中的字段说明:
extends:描述父类类名;
singleton:描述类是否为单例;
markdown:不知道是干什么的,反正解析出来(*^_^*)……
xtype:类注册的xtype,如果没有注册xtype,其值为"(undefined)";
cfg:关于配置项的名称和值类型等信息;
property:关于类对象的属性的名称和类型的信息;
methods:关于函数名,参数类型信息和返回类型等信息,忽略了optional信息;
events:关于event的信息和event的处理函数传入参数的类型信息等,忽略了optional信息。

作为一个假反射,当然还要费一点功夫啦!比如,你得告诉我ext源码在什么地方对吧~不然我怎么去解析啊。那么,你告诉我的方式就是,写一个reflect.js文件(我在压缩文件中放了一份),内容如下:
{'ext.src':'/ext-4.0.1/src/'}
很明显,把这个文件放到根目录下面就可以了。因此,Ext.Reflect不能解析的有缩小范围了,只能是在配置路径下面的才能“反射”。

实际上这个类可能没啥用,哈哈!不过也有可能有大用%#&*@¥+$~=`…

小心翼翼的吼一下,我隐隐的感觉在Ext上应该有适当的方式可以实现“真反射”,而且效用无限!

下面开始贴代码!Ext.Reflect.js是源码,Ext.Reflect.test.js是测试代码。(使用FireDug调试)

//Ext.Reflect.js
Ext.define('Ext.Reflect', {
	extend:'Ext.util.Observable',
	constructor:function(target){
		var me=this;
		if(!(me instanceof Ext.Reflect))
			return new Ext.Reflect(target);
		if(!Ext.Reflect.classes)
			Ext.Reflect.classes={};
		var className;
		if(typeof target=='string')
			className=target;
		else
			className=Ext.getClassName(target);
		if(className=='Ext'){
			this.failed=false;
			return;
		}
		className=className.replace(/^\s*|\s*$/,'');
		me.cfg=[];
		me.properties=[]
		me.methods=[];
		me.events=[];
		if(Ext.Reflect.classes[className]){
			classInfo=Ext.Reflect.classes[className];
			me.cfg=classInfo.cfg
			me.properties=classInfo.properties;
			me.methods=classInfo.methods;
			me.events=classInfo.events;
			me.singleton=classInfo.singleton;
			me.markdown=classInfo.markdown;
			me.extends=classInfo.extends;
			me.xtype=classInfo.xtype;
		}else{
			var config;
			if(!Ext.Reflect.classPath){
				Ext.Ajax.request({
					url:'/reflect.js',
					async:false,
					success:function(response,options){
						eval('config='+response.responseText);
					}
				});
				if(!config||!config['ext.src']){
					me.failed=true;
					return;
				}
				Ext.Reflect.classPath=config['ext.src'];
			}
			var text,targetUrl=className.replace(/\./g,'/').replace(/^Ext\//g,Ext.Reflect.classPath);
			Ext.Ajax.request({
				url:targetUrl,
				async:false,
				success:function(response,options){text=response.responseText;},
				failure:function(response,options){me.failed=true;}
			});
			if(this.failed)
				return;
			var p=0,l=0;
			var method,line,matches,inner=false,desc='',last,token,row=0,temp='',overleap=false;
			function getLine(){
				var s;
				while('\n'.indexOf(text.substr(p++,1))==-1);
				s=text.substring(l,p);
				l=p;
				return s;
			}
			while(p<text.length){
				line=getLine();
				row++;
				if(line.match(/^\s*\/\*\*/g)){
					inner=true;
					overleap=false;
					continue;
				}else if(line.match(/\*\/\s*$/g)){
					if(last){
						last.desc=desc.replace(/\n\s*$/g,'');
						if(temp=='@property'&&!last.name)
							me.properties.pop();
					}
					inner=false;
					if(temp=='@method'&&last&&!last.isConstructor){
						while(p<text.length){
							line=getLine();
							if(line.match(/^\s*\/\*\*/g)){
								inner=true;
								overleap=false;
								break;
							}
							matches=line.match(/^\s*\w+\s*\:/);
							if(matches){
								last.name=matches[0].replace(/^\s*|\s*\:$/g,'');
								break;
							}
						}
					}
					desc="";
					temp='';
					last=null;
					continue;
				}else if(inner){
					matches=line.match(/\s*\*\s*/g);
					if(!matches)
						continue;
					line=line.substr(matches[0].length);
					matches=line.match(/^@\w+/g);
					if(!matches){
						if(!overleap)
							desc+=line.replace(/\n$/g,'');
						continue;
					}
					token=matches[0];
					line=line.substr(token.length);
					switch(token){
						case '@cfg':
							matches=line.match(/^\s*\{([^\}]+)\}/);
							if(!matches)
								continue;
							temp={'type':matches[1]};
							line=line.substr(matches[0].length).replace(/^\s*/,'');
							matches=line.match(/^\w+/);
							last={'name':matches[0],'type':temp.type,'optional':false,'hidden':false,'desc':''};
							temp='@cfg';
							line=line.substr(matches[0].length).replace(/^\s*/,'');
							matches=line.match(/\(([\w]+)\)/g);
							if(matches&&matches[0]=='(Optional)'){
								last.optional=true;
								line=line.substr(matches[0].length).replace(/^\s*/,'');
							}
							matches=line.match(/^@\w+/g);
							if(matches&&matches[0]=='@hide'){
								last.hidden=true;
								line=line.substr(matches[0].length).replace(/^\s*/,'')
							}
							last.desc="";
							me.cfg.push(last);
							break;
						case '@property':
							matches=line.match(/^\s*\w+/);
							desc=desc.replace(/\n\s*$/g,'');
							if(!matches)
								continue;
							line=line.substr(matches[0].length);
							if(temp=='@property'&&last&&!last.name){
								last.name=matches[0].replace(/^\s*/g,'');
							}else{
								last={'name':matches[0].replace(/^\s*/g,''),'type':'unkown','desc':''};
								me.properties.push(last);
							}
							temp='@property';
							break;
						case '@type':
							matches=line.match(/^\s*\w+/);
							desc=desc.replace(/\n\s*$/g,'');
							if(!matches)
								continue;
							line=line.substr(matches[0].length);
							if(last&&temp=='@property'){
								last.type=matches[0].replace(/^\s*/g,'');
							}else{
								last={'name':null,'type':matches[0].replace(/^\s*/g,''),'desc':''};
								me.properties.push(last);
							}
							temp='@property';
							break;
						case '@constructor':
							last={'name':'(constructor)','args':[],'return':'void','isConstructor':true,'desc':''}
							me.methods.push(last);
							temp='@method';
							overleap=true;
							continue;
							break;
						case '@param':
							matches=line.match(/^\s*\{([^\}]+)\}/);
							if(!matches)
								continue;
							line=line.substr(matches[0].length);
							if(last){
								temp={'type':matches[1],'temp':temp};
								matches=line.match(/^\s*\w*/);
								if(matches){
									line=line.substr(matches[0].length);
									last.args.push({'name':matches[0].replace(/^\s*/g,''),'type':temp.type});
								}else{
									last.args.push({'name':'(undefined)','type':temp.type});
								}
								temp=temp.temp;
							}else{
								if(temp==''||temp=='@method'){
									last={'name':'(ailed)','args':[],'return':'void','isConstructor':false,'desc':''};
									temp={'type':matches[1]};
									matches=line.match(/^\s*\w*/);
									if(matches){
										line=line.substr(matches[0].length);
										last.args.push({'name':matches[0].replace(/^\s*/g,''),'type':temp.type});
									}
									me.methods.push(last);
									temp='@method';
								}
							}
							break;
						case '@return':
							matches=line.match(/^\s*\{([^\}]+)\}/);
							if(!matches)
								continue;
							line=line.substr(matches[0].length);
							if(last){
								last['return']=matches[1];
							}else{
								last={'name':'(ailed)','args':[],'return':matches[1],'isConstructor':false,'desc':''}
								me.methods.push(last);
							}
							overleap=true;
							temp='@method';
							continue;
							break;
						case '@event':
							matches=line.match(/^\s*\w+/);
							if(!matches)
								last={'name':'(ailed)','args':[],'desc':''};
							else
								last={'name':matches[0].replace(/^\s*/g,''),'args':[],'desc':''};
							me.events.push(last);
							temp='@event';
							break;
						case '@class':
							matches=line.match(/\s*\w+(\.\w+)*/g);
							if(!matches)
								continue;
							me.className=matches[0].replace(/^\s*/g,'');
							continue;
							break;
						case '@singleton':
							me.singleton=true;
							continue;
							break;
						case '@markdown':
							me.markdown=true;
							continue;
							break;
						case '@extends':
							matches=line.match(/^\s*\w+(\.\w+)*/);
							if(matches)
								me.extends=matches[0];
							continue;
							break;
						case '@xtype':
							matches=line.match(/^\s*\w+(\.\w+)*/);
							if(matches)
								me.xtype=matches[0].replace(/^\s*/g,'');
							continue;
							break;
						default:
					}
					desc+=line.replace(/^\s*|\n?$/g,'');
				}
			}
			me.singleton=(!me.singleton)?false:me.singleton;
			me.markdown=(!me.markdown)?false:me.markdown;
			me.extends=(!me.extends)?'Object':me.extends;
			me.xtype=(!me.xtype)?'(undefined)':me.xtype;
			Ext.Reflect.classes[className]=me;
		}
	}
	//here
});

//Ext.Reflect.test.js
Ext.onReady(function(){
	var reflect=new Ext.Reflect('Ext.Ajax');
//	var reflect=new Ext.Reflect('Ext.Editor');
	reflect=new Ext.Reflect('Ext.Editor');
	reflect=new Ext.Reflect('Ext.Ajax');
	reflect=new Ext.Reflect('Ext.Editor');
	document.getElementById('content').innerHTML+='<br/>Ext.Reflect.test:onReady';
});

这个是在FireBug下面的截图


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值