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 和call
50          */
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
    };
}

时间: 2024-11-15 01:37:59

javascript的DI的相关文章

AngularJS中的DI

AngularJS中的DI一直以为Angular中的DI是很高大上的东西,也自己写过一个DI的demo,知道其中的难点就是最后动态代码的执行:我现在知道了参数的值,也知道了我要执行的方法/创建对象的类,那么在参数个数是动态的情况下,怎么才能执行这个方法或者新建对象呢?在我的demo中我选择的是用eval可是当我看到AngularJS源码中有如下的语句时: 1 switch (self ? -1 : args.length) { 2 case 0: return fn(); 3 case 1: r

JavaScript中实现DI的原理(二)

JavaScript中实现DI的原理 在JavaScript中实现DI,看起来难,实际上原理很简单,它的核心技术是Function对象的toString().我们都知道,对一个函数对象执行toString(),它的返回值是函数的源码,知道了这一点,接下来就简单的:我获取了函数源码,然后我对函数的声明进行解析,伪码如下: var giveMe = function(config) { }; var registry = {}; var inject = function(func, thisFor

JavaScript中实现DI的原理

什么是依赖注入 按照上面图的流程中我们可以知道我们需要实现这么几件事: 提供一个服务容器 为目标函数注册需要的依赖 获取目标函数注册的依赖项 通过依赖项来查询对应服务 将获取的依赖项传入目标函数 提供一个服务容器 //假装提供一些服务 var services = { A: () => {console.log(1)}, B: () => {console.log(2)}, C: () => {console.log(3)} } 为目标函数注册需要的依赖 // 目标函数 function

Javascript写入txt和读取txt文件的方法

文章主要介绍了Javascript写入txt和读取txt文件的方法,需要的朋友可以参考下1. 写入 FileSystemObject可以将文件翻译成文件流. 第一步: 例: 复制代码 代码如下: Var fso=new ActiveXObject(Scripting.FileSystemObject); 创建一个可以将文件翻译成文件流的对象. 第二步:用于创建一个textStream 对象 括号里边有三个属性 1. 文件的绝对路径 2. 文件的常数 只读=1,只写=2 ,追加=8 等权限.(Fo

流行的JavaScript库 ——jQuery

1.为了简化 JavaScript 的开发, 一些 JavsScript 库诞生了. JavaScript 库封装了很多预定义的对象和实用函数.能帮助使用者建立有高难度交互的 Web2.0 特性的富客户端页面, 并且兼容各大浏览器.当前流行的 JavaScript 库有:jQuery, MooTools, Prototype, Dojo, YUI, EXT_JS  DWR 2.jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多javascript高手加入其team. j

js 实现 di

前些时候有使用过AngularJS一些时间,最大的感受就是Angular完全颠覆了我们开发Web应用的方式,自己被其许多耳目一新的设计思想所折服. 首先想说的就是依赖注入(DI),这也意味着,你在使用某一个模块时,不需要去手动require()一下,你需要的模块会自己注入到的函数所在的作用域中,如: JavaScript 1 2 3 4 5 app.service('PersonService', function ($http) {     this.addPerson = function

最近面试的题目(WEB、Service、SQL、JavaScript)

整理一下最近面试被问到的主要题目.由于本人主要是做WEB及WEB SERVICE这块,使用的语言主要是C#,数据库主要用到的也是MSSQL.所以就分成这些块来整理(有些是在面试之后才意识到回答不对),也包括部分别人被问及的. 一.HTML.CSS position有哪几种值,各是怎么使用的? 一个左右部局,如何实现? 二.JAVASCRIPT, JS FRAMEWORK document.onload与jQuery中的ready有何区别? 什么是闭包?写一下. jQuery中有个叫"on&quo

JavaScript实现常用的排序算法

▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排序.希尔排序.直接选择排序 ▓▓▓▓▓▓ 交换排序 交换排序是一类在排序过程中借助于交换操作来完成排序的方法,基本思想是两两比较排序记录的关键字,如果发现两个关键字逆序,则将两个记录位置互换,重复此过程,直到该排序列中所有关键字都有序为止,接下来介绍交换排序中常见的冒泡排序和快速排序 ▓▓▓▓▓▓

FCC上的javascript算法题之中级篇

FCC中的javascript中级算法题解答 中级算法的题目中用到了很多js的知识点,比如迭代,闭包,以及对json数据的使用等等,现在将自己中级算法的解答思路整理出来供大家参考讨论.欢迎大家提出新的思路,写出更简单的解法. 1.给一个包含两个数字的数组.返回这两个数字和它们之间所有数字的和. 说明:最小的数字并非总在最前面 如:sumAll([4, 1]) 应该返回 10. sumAll([5, 10]) 应该返回 45. function sumAll(arr) { var max=Math