这篇文章是探索对于Angular开发者来说既熟悉又陌生的概念:依赖注入。
我们在定义控制器、服务(甚至是指令)的时候通常会依赖一些服务,例如下面这样:
|
|
实现过程
按照科学方法(提出假设——>进行实验——>得出结论)可以先猜想一下Angular的实现过程:
- 解析参数。
提取所需的服务(即函数参数)显得有点麻烦,因为js并没有提供原生的方法,可能需要手动实现。
一种常用的解析字符串的方法就是用正则表达式。
- 实例化服务
得到了参数之后就需要根据参数来生成其对应的服务实例了,因为Angular的服务是单例模式,所以很可能会用到缓存的方式来来避免多个相同的服务。
- 执行定义函数
传入服务并调用我们的声明函数,创建对应的控制器/服务/指令等。
源码探究
依赖解析
我们以(Angular1.3)[https://cdn.bootcss.com/angular.js/1.3.20/angular.js]版本源码为例。
|
|
简而言之,这一部分代码流程也很简单:获取函数源码,取到函数头部,分割放入数组。
这样就获得了我们依赖注入所需要的参数名,这是针对前面所说的第二种情况,第一种情况则很简单,直接从数组中提取就行。
服务实例
|
|
这一部分代码完整的贴出来看起来会比较费解,因为它的执行方式很像递归函数。
简而言之就是执行服务的定义函数,然后在执行环境(this指针上)绑定对应的函数,然后返回改执行环境。
这样依赖它的函数就可以访问服务内部的函数了
同时也用了一个json对象来(locals变量)缓存服务。
调用函数
|
|
结论
从截取的部分源码分析来看,基本上如开始所想。解析依赖服务,然后以回调的方式找到所需服务并调用函数。
源码地址:
https://cdn.bootcss.com/angular.js/1.3.20/angular.js
参考文章:
《The “Magic” behind AngularJS Dependency Injection》
一部由众多技术专家推荐, 帮你成为具有全面能力和全局视野工程师的进阶利器—— 《了不起的JavaScript工程师》出版了! 点击下方链接即刻踏上进阶之路!
- 淘宝:https://detail.tmall.com/item.htm?id=600756390664
- 京东:https://item.jd.com/12562349.html?dist=jd
- 当当:http://product.dangdang.com/27922044.html