学习AngularJS的原因之一就是觉得他的DI很牛叉,为了更好的学习,在研究源码之前,想自己按照自己的思路先实现个DI,希望这个思路能够对
学习源码有帮助。

 (function(){
var config;
var di={};
//用来缓存已经生成的对象
var beans=new Array();
di.config=function(conf){
this.config=conf;
return di;
}; /*获取一个方法的参数列表,要求所有注入的参数都已$开头
第二个正则表达是后面的 g 很重要,它表示搜索到第一个之后接着往后搜
没有这个g ,就只能match第一个参数。
这里的参数列表指的就是代码中写的参数列表,不是带入参数后的参数类表
比如有一个方法:
function Fn(a,b,c,c1){}
参数列表就是一个有四个字符串组成的数组:["a","b","c","c1"]
因为需要有参数的名字去匹配参数的类型
*/
var getArguments=function(fun){
return fun.toString().match(/\(.*\)/)[0].match(/\$\w+/g);
};
//核心方法
di.getBean=function(beanName){
//查看缓存,有的话直接返回
if(beans[beanName]!=undefined)
return beans[beanName];
var fn=this.config[beanName];
if(fn==undefined) return;
var args=getArguments(fn);
var argss=new Array();
var objstr="";
var index=0;
var obj;
for(var i in args){
argss[i]=(di.getBean(args[i]));
objstr+="argss["+index+"],";
index++;
}
objstr=objstr.substring(0, objstr.length-1);
objstr="obj=new (fn)("+objstr+"); ";
/*整个DI能够实现就靠这个eval方法了,
它接受一个String参数,并把String里面的内容按照Javasript的标准编译并执行
最牛叉的是eval里面的变量也遵循Javascript的函数作用域:也就是变量可以定义在eval外面
*/
/*
当然这里也可以用apply,或者call,不过总有这样那样的问题,可能是自己对这两个方法不够了解吧
先用eval实现了,以后再研究apply 和call
*/
eval(objstr);
beans[beanName]=obj;
return obj;
};
window.di=di;
})(window);

下面是个例子,

 function Person(){
this.name="Mike";
this.address="China"; this.getName=function(){
return this.name;
};
this.getAddress=function(){
return this .address;
};
}
function Service($person){
this.work=function(){
return $person.getName()+" is living in "+$person.getAddress();
};
} function Adaptor($person,$service){
this.alertt=function(){
var k=$service.work();
alert(k);
};
}

有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的更多相关文章

  1. 细数Javascript技术栈中的四种依赖注入

    作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...

  2. AngularJS中的DI

    AngularJS中的DI一直以为Angular中的DI是很高大上的东西,也自己写过一个DI的demo,知道其中的难点就是最后动态代码的执行:我现在知道了参数的值,也知道了我要执行的方法/创建对象的类 ...

  3. 每个JavaScript开发人员应该知道的33个概念

    每个JavaScript开发人员应该知道的33个概念 介绍 创建此存储库的目的是帮助开发人员在JavaScript中掌握他们的概念.这不是一项要求,而是未来研究的指南.它基于Stephen Curti ...

  4. 30行代码让你理解angular依赖注入:angular 依赖注入原理

    依赖注入(Dependency Injection,简称DI)是像C#,java等典型的面向对象语言框架设计原则控制反转的一种典型的一种实现方式,angular把它引入到js中,介绍angular依赖 ...

  5. angular 依赖注入原理

    依赖注入(Dependency Injection,简称DI)是像C#,java等典型的面向对象语言框架设计原则控制反转的一种典型的一种实现方式,angular把它引入到js中,介绍angular依赖 ...

  6. JavaScript中实现DI的原理(二)

    JavaScript中实现DI的原理 在JavaScript中实现DI,看起来难,实际上原理很简单,它的核心技术是Function对象的toString().我们都知道,对一个函数对象执行toStri ...

  7. 原创:Javascript DI!Angular依赖注入的实现原理

    DI是Angular的特色功能,而在Angular 2.0的计划中,DI将成为一个独立的模块,参见 https://github.com/angular/di.js 这意味着它也有机会被用于nodej ...

  8. JavaScript中实现DI的原理

    什么是依赖注入 按照上面图的流程中我们可以知道我们需要实现这么几件事: 提供一个服务容器 为目标函数注册需要的依赖 获取目标函数注册的依赖项 通过依赖项来查询对应服务 将获取的依赖项传入目标函数 提供 ...

  9. JavaScript实现常用的排序算法

    ▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排 ...

随机推荐

  1. Java EE规范是如何制定的

    我们经常做的JAVA EE开发实际上都是遵从了JAVA EE的规范进行的,那么这些规范是如何制定的呢? 这就不得不提到JCP这个组织了. JCP( Java Community Process)可以翻 ...

  2. 每天一个Linux命令(7)pwd命令

    pwd命令以绝对路径的方式显示用户当前工作目录.命令将当前目录的全路径名称(从根目录)写入标准输出.全部目录使用/分隔.第一个/表示根目录,最后一个目录是当前目录.     (1)用法介绍: pwd[ ...

  3. 【leetcode刷题笔记】Letter Combinations of a Phone Number

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  4. Linux 上关于iptables

    有几个命令: 1.service iptables staus   2.service iptables start    3.service iptables restart   有个配置文件/ec ...

  5. 算法(Algorithms)第4版 练习 2.1.27

    package com.qiusongde; import edu.princeton.cs.algs4.StdOut; public class Exercise2127 { public stat ...

  6. 启动Hive时报错

    报错信息如下 Logging initialized -bin/lib/hive-common-.jar!/hive-log4j.properties Exception in thread &quo ...

  7. HDU 3954 Level up(多颗线段树+lazy操作)

    又是一开始觉得的水题,结果GG了好久的东西... 题意是给你n个英雄,每个英雄开始为1级经验为0,最多可以升到k级并且经验一直叠加,每一级都有一个经验值上限,达到就升级.接着给你两种操作:W li r ...

  8. BZOJ 3943 [Usaco2015 Feb]SuperBull:最大生成树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3943 题意: 有n只队伍,每个队伍有一个编号a[i]. 每场比赛有两支队伍参加,然后选一支 ...

  9. php深入浅出session

    1. session概念 0 2. http协议与状态保持 0 3. 理解cookie 0 4. php中session的生成机制 2 5. php中session的过期回收机制 3 6. php中s ...

  10. php 冒泡排序原理

    $start = microtime(true);   $popArr = array(6,3,23,1,5,100,399,99,66);   echo '6,3,23,1,5,100,399,99 ...