首页 > 代码库 > javascript的DI
javascript的DI
学习AngularJS的原因之一就是觉得他的DI很牛叉,为了更好的学习,在研究源码之前,想自己按照自己的思路先实现个DI,希望这个思路能够对
学习源码有帮助。
1 (function(){ 2 var config; 3 var di={}; 4 //用来缓存已经生成的对象 5 var beans=new Array(); 6 di.config=function(conf){ 7 this.config=conf; 8 return di; 9 };10 11 /*获取一个方法的参数列表,要求所有注入的参数都已$开头12 第二个正则表达是后面的 g 很重要,它表示搜索到第一个之后接着往后搜13 没有这个g ,就只能match第一个参数。14 这里的参数列表指的就是代码中写的参数列表,不是带入参数后的参数类表15 比如有一个方法:16 function Fn(a,b,c,c1){}17 参数列表就是一个有四个字符串组成的数组:["a","b","c","c1"]18 因为需要有参数的名字去匹配参数的类型19 */20 var getArguments=function(fun){21 return fun.toString().match(/\(.*\)/)[0].match(/\$\w+/g);22 };23 //核心方法24 di.getBean=function(beanName){25 //查看缓存,有的话直接返回26 if(beans[beanName]!=undefined)27 return beans[beanName];2929 var fn=this.config[beanName];30 if(fn==undefined) return;31 var args=getArguments(fn);32 var argss=new Array();33 var objstr="";34 var index=0;35 var obj;36 for(var i in args){37 argss[i]=(di.getBean(args[i]));38 objstr+="argss["+index+"],";39 index++;40 }41 objstr=objstr.substring(0, objstr.length-1);42 objstr="obj=new (fn)("+objstr+"); ";43 /*整个DI能够实现就靠这个eval方法了,44 它接受一个String参数,并把String里面的内容按照Javasript的标准编译并执行45 最牛叉的是eval里面的变量也遵循Javascript的函数作用域:也就是变量可以定义在eval外面46 */47 /*48 当然这里也可以用apply,或者call,不过总有这样那样的问题,可能是自己对这两个方法不够了解吧49 先用eval实现了,以后再研究apply 和call50 */51 eval(objstr);52 beans[beanName]=obj;53 return obj;54 };55 window.di=di;56 })(window);
下面是个例子,
1 function Person(){ 2 this.name="Mike"; 3 this.address="China"; 4 5 this.getName=function(){ 6 return this.name; 7 }; 8 this.getAddress=function(){ 9 return this .address;10 };11 }12 function Service($person){13 this.work=function(){14 return $person.getName()+" is living in "+$person.getAddress();15 };16 }17 18 function Adaptor($person,$service){19 this.alertt=function(){20 var k=$service.work();21 alert(k);22 };23 }
有Person,Service,Adaptor三个类,Service类依赖Person来组装语句,Adaptor类依赖Service类来显示,只要有下面的代码就能运行了
var conf={ "$person":Person, "$adaptor":Adaptor, "$service":Service};di.config(conf).getBean("$adaptor").alertt();
目前这种DI有个缺陷就是没法再组装时决定类的状态。比如一开始new一个Person时想通过构造方法给name赋值,以上的方式是不能直接做不到的。
只能通过一个间接地方式,如下:
function Person(){ this.name="Mike"; this.getName=function(){ return this.name; }; this.setName=function($name){ this.name=$name.Name; };}function Name(){ this.NAME="Tom";}//然后在Service中使用Person前重新给name赋值function Service($person,$name){ this.work=function(){ $person.setName($name.NAME); return $person.getName()+" is living in China"; //这里就成了 Tom is living in China };}
javascript的DI
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。