JavaScript中实现DI的原理

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

var giveMe = function(config) {
}; var registry = {};
var inject = function(func, thisForFunc) {
// 获取源码
var source = func.toString();
// 用正则表达式解析源码
var matcher = source.match(/..表达式有些复杂,省略../);
// 解析结果是各个参数的名称
var objectIds = ....
// 查阅出相应的对象,放到数组中准备作为参数传过去
var objects = [];
for (var i = 0; i < objectIds.length; ++i)
objects.push(registry[objectIds[i]]);
// 调用这个函数,并且把参数传过去
func.apply(thisForFunc || func, objects)
}; inject(giveMe)

当然,一个实际的DI系统需要考虑的问题比这要多很多,但是这段代码用来表现原理应该足够了。

接下来我们再来看Angular中的DI实现:

在Angular中,所有主要编程元素都需要通过某种方式注册进去,比如myModule.service('serviceName', function().... 这实际上就是把后面这个函数加入到一个容器中,要注意的是:angular全面实现了延迟初始化,也就是说,当这个对象没有被别人需要的时候,它是不会被创建的,这样对于提高性能有一定的帮助,特别是加快了启动速度。

这里一个有趣的问题是:Angular的容器是什么。Angular不存在真正的全局对象,所以你可以放心的在同一个页面中放多个app,而不用担心他们互相干扰,但是容器又需要一个众所周知的地方来存放这些“名字和对象”的注册表(Registry),在Angular中,这个注册表就叫做module,所以,现在你应该知道为什么module的地位很重要了吧?不过一个app中可以存在很多不同名字的module,它们之间存在某些依赖关系,而这体现在module的声明语法中:angular.module('someModule', ['dep1', 'dep2]),这样划分module有利于程序的文件组织。

根据DI的原理,一个自然的推论就是:被注入的对象通常都是单例,因为创建了一个,就可以始终使用它了,不需要多次创建。因此,如果你需要在angular中跨controller共享数据或者通讯,那么你可以创建一个service/value/constant等,然后把它们分别注入到两个controller中,而这两个controller将自然而然的共享同一个对象。

JavaScript中实现DI的原理(二)的更多相关文章

  1. JavaScript中实现DI的原理

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

  2. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  3. 详解javascript中this的工作原理

    在 JavaScript 中 this 常常指向方法调用的对象,但有些时候并不是这样的,本文将详细解读在不同的情况下 this 的指向. 一.指向 window: 在全局中使用 this,它将会指向全 ...

  4. JavaScript中this的工作原理以及注意事项

    在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this  ...

  5. javaScript中闭包的工作原理

    一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话 ...

  6. Javascript中的对象和原型(二)(转载)

    上一篇中提到了JavaScript中对象的创建的一些基本操作,接下来讨论下继续讨论. 一 工厂模式 我们知道,要创建一个对象我们可以用如下代码: var user = new Object(); // ...

  7. javascript中new操作符的原理

    javascript中的new是一个语法糖,对于学过c++,java 和c#等面向对象语言的人来说,以为js里面是有类和对象的区别的,实现上js并没有类,一切皆对象,比java还来的彻底 new的过程 ...

  8. 【干货理解】理解javascript中实现MVC的原理

    理解javascript中的MVC MVC模式是软件工程中一种软件架构模式,一般把软件模式分为三部分,模型(Model)+视图(View)+控制器(Controller); 模型:模型用于封装与应用程 ...

  9. JavaScript 中this的实现原理

    学懂 JavaScript 言语,一个标志就是了解下面两种写法,或许有不一样的成果. <blockquote "=""> var obj = { foo: f ...

随机推荐

  1. 【医学影像】《Dermatologist-level classification of skin cancer with deep neural networks》论文笔记

    这是一篇关于皮肤癌分类的文章,核心就是分类器,由斯坦福大学团队发表,居然发到了nature上,让我惊讶又佩服,虽然在方法上没什么大的创新,但是论文本身的工作却意义重大,并且这篇17年见刊的文章,引用量 ...

  2. python之类与对象(2)

    3. 类函数的进阶 3.1 类函数调用类属性 关于类函数调用类属性,我们尝试修改前一节的内容,以我们在之前学习的内容,调用属性直接用%+属性就可以了,那我们来试一下: 看到了程序有报错,这其实是因为在 ...

  3. bzoj3280: 小R的烦恼(最小费用最大流)

    Description 小R最近遇上了大麻烦,他的程序设计挂科了.于是他只好找程设老师求情.善良的程设老师答应不挂他,但是要 求小R帮助他一起解决一个难题.问题是这样的,程设老师最近要进行一项邪恶的实 ...

  4. C#集合之队列

    队列是其元素按照先进先出(FIFO)的方式来处理的集合. 队列使用System.Collections.Generic名称空间中的泛型类Queue<T>实现.在内部,Queue<T& ...

  5. odoo 的一些orm 操作

    1.基础文件及目录结构 在认识odoo ORM框架前,先介绍一下odoo中模块目录结构.     data:存放模块预制数据 i18n:存放国际化文件 models:存放模型等py代码 securit ...

  6. PIE SDK与GeoServer结合说明文档

    1.  GeoServer简介 GeoServer是OpenGIS Web服务器规范的J2EE实现的社区开源项目,利用GeoServer可以方便的发布地图数据,允许用户对特征数据进行更新.删除.插入操 ...

  7. element-ui多层嵌套表格数据删除

    很多表格都要一个移除的功能,所谓移除,就是前端把表格的数据删除,普通的表格删除很简单,调用数据的删除方法就行.但是当表格是多层的嵌套类型时,就不能再使用普通的删除方法了.下面介绍一种自己在项目中用的方 ...

  8. linux操作python

    Linux安装python3: sudo apt-get install python3.5 安装python库 sudo apt-get install python3-setuptools sud ...

  9. module.exports,exports,export和export default,import与require区别与联系

    还在为module.exports.exports.export和export default,import和require区别与联系发愁吗,这一篇基本就够了! 一.首先搞清楚一个基本问题: modu ...

  10. input获得焦点时改变placeholder文本的样式

    HTML: <input type="text" placeholder="sample text"/> CSS: input::-webkit-i ...