您的位置:首页 > Web前端 > JavaScript

javascript面向对象包装类Class封装类库剖析

2013-01-24 18:06 1101 查看
/** *Klass.js-copyright@dedfat *version1.0 *https://github.com/ded/klass *Followoursoftwarehttp://twitter.com/dedfat:) *MITLicense */ !function(context,f){ //fnTest用来验证是否可能通过正则找出调用super父类方法的方法 varfnTest=/xyz/.test(function(){xyz;})?/\bsupr\b/:/.*/, noop=function(){}, proto='prototype', isFn=function(o){ returntypeofo===f; }; //基础类 functionklass(o){ returnextend.call(typeofo==f?o:noop,o,1); } //包装成一个借用super同名方法的函数 functionwrap(k,fn,supr){ returnfunction(){ //缓存原this.super vartmp=this.supr; //暂把this.super改造成借用super的同名方法above //供o里显式的声明(fnTest.text(fn)==true)要借用super的同名方法使用 this.supr=supr[proto][k]; //借用执行并保存返回值 varret=fn.apply(this,arguments); //恢复原this.super this.supr=tmp; //返回返回值,保证wrap后的返回值跟原来一致 returnret; }; } //如果o和super有同名方法,且o显式声明借用super的同名方法,就wrap成一个待执行函数供使用 //如果没有显式的声明借用super的同名方法,或者是o独有的方法,或者不是方法就直接用 functionprocess(what,o,supr){ for(varkino){ //如果是非继承方法,按方法注释规则执行,最终都放进what if(o.hasOwnProperty(k)){ what[k]=typeofo[k]==f &&typeofsupr[proto][k]==f &&fnTest.test(o[k]) ?wrap(k,o[k],supr):o[k]; } } } //继承方法的实现,fromSub是用来控制是否继承而来,上面的klass里面fromSub是1,表明非继承而来,构造函数不借用super执行 functionextend(o,fromSub){ //noop做为媒介类实现原型继承的解除引用 noop[proto]=this[proto]; varsupr=this, prototype=newnoop(),//创建实例对象供原型继承使用,解除引用 isFunction=typeofo==f, _constructor=isFunction?o:this,//如果o是一个构造方法就用,否则由this来决定构造函数 _methods=isFunction?{}:o,//如果o是一个{...}应该用methods放到fn原型里,如果里面有initialize就是构造函数,如果o是函数就由上面_constructor决定o是构造函数 fn=function(){//因为kclass借助了kclass,所以最终实际上返回的就是fn,fn其实就新类的构造函数 //1如果o是{...}就会被methods直接过滤并添加到fn的原型里,如果o里面有initialize,那么fn的原型里就有initialize,那么它就是构造方法 //2如果o是function,methods什么也添加不到fn的原型里,但是_constructor会接受o当构造函数 //3如果o是{....},同时里面也没有initialize,那么就是this当构造函数,如果在klass里由call决定,显然构造函数是noop,如果在非基础类里,构造函数就是父类的构造函数 //由于o不是函数不会自动调用父类的构造函数,只是把父类的构造函数当做当前类的构造函数----这都是由于this的指向决定的 console.log(this); if(this.initialize){ this.initialize.apply(this,arguments); }else{ //调用父类构造方法 //如上面3,o不是函数,不会调用父类的构造方法 //基础类无父类,不会调用父类构造方法 fromSub||isFn(o)&&supr.apply(this,arguments); //调用本类构造方法 //参考上面2,3要么是noop要么是o console.log(_constructor==noop); _constructor.apply(this,arguments); } }; //构造原型方法的接口 fn.methods=function(o){ process(prototype,o,supr); fn[proto]=prototype; returnthis; }; //执行实现新类原型,保证新类的constructor fn.methods.call(fn,_methods).prototype.constructor=fn; //保证新类可以被继承 fn.extend=arguments.callee; //添加实例方法或者静态方法,statics:静态方法,implement实例方法 fn[proto].implement=fn.statics=function(o,optFn){ //保证o是一个object对象,如果o是一个字符串,那么就是添一个方法的情况,如果o是一个object对象说明是批量添加的 //因为要从o里面拷贝 o=typeofo=='string'?(function(){ varobj={}; obj[o]=optFn; returnobj; }()):o; //添加实例方法或者静态方法,statics:静态方法,implement实例方法 process(this,o,supr); returnthis; }; returnfn; } //后台用,nodejs if(typeofmodule!=='undefined'&&module.exports){ module.exports=klass; }else{ varold=context.klass; //防冲突 klass.noConflict=function(){ context.klass=old; returnthis; }; //前台浏览器用 //window.kclass=kclass; context.klass=klass; } }(this,'function');
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  类库 Class