JavaScript依赖注入的实现思路
JavaScript依赖注入的实现思路
如今各个框架都在模块化,连前端的javascript也不例外。每个模块负责一定的功能,模块与模块之间又有相互依赖,那么问题来了:javascript的依赖注入如何实现?(javascript的依赖注入,各大框架都有相应的实现,这里只学习实现思路)
如下需求:
假设已经有定义好的服务模块Key-Value集合,func为添加的新服务,参数列表为服务依赖项。
var services = { abc : 123, def : 456, ghi : 789 }; // 假设已定义好某些Service
function Service(abc, ghi){
this.write = function(){
console.log(abc);
console.log(ghi);
}
}
function Activitor(func){
var obj;
// 实现
return obj;
}
解决思路:
通过某种机制(反射?),取出该func定义的参数列表,并一一赋值。然后再通过某种机制(Activitor?),实例化该func。
解决方案:
一、获取func的参数列表:
如何获取参数列表呢?我首先想到的是反射机制。那javascript里面有没有反射呢?应该有吧,我目前只知道使用eval(str)函数,但貌似并没有获取参数列表的相关实现。再看func.arguments定义,此属性只在调用func并传递参数时才有效,也不能满足需求。
那能不能通过处理func.toString()后的字符串获取参数列表呢?
上手试试吧:
function getFuncParams(func) {
var matches = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m);
if (matches && matches.length > 1)
return matches[1].replace(/\s*/, '').split(',');
return [];
};
至此获得func参数列表数组。
二、根据参数列表寻找依赖:
得到了参数列表,即得到了依赖列表,将依赖项作为参数传入也就很简单了。
var params = getFuncParams(func);
for (var i in params) {
params[i] = services[params[i]];
}
三、传递依赖项参数并实例化:
我们知道,javascript里面有func.constructor有call(thisArg,[arg[,arg,[arg,[…]]]])和apply(thisArg,args…)两个函数,都可以实现实例化func操作。其中call函数第一个参数为this指针,剩余为参数列表,这个适合在已知func参数列表的情况下使用,不能满足我的需求。再看第二个apply函数,第一个参数也为this指针,第二个参数为参数数组,其在调用时会自动为func的参数列表一一赋值,正好满足我的需求。
代码大概如下:
function Activitor(func){
var obj = {};
func.apply(obj, params);
return obj;
}
至此我们能够创建该func的实例,并传递该func需要的参数。
四、打印测试一下吧:
完整代码:
var
// 假设已定义好某些Service
services = { abc: 123, def: 456, ghi: 789 }, // 获取func的参数列表(依赖列表)
getFuncParams = function (func) {
var matches = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m);
if (matches && matches.length > 1)
return matches[1].replace(/\s+/, '').split(',');
return [];
}, // 根据参数列表(依赖列表)填充参数(依赖项)
setFuncParams = function (params) {
for (var i in params) {
params[i] = services[params[i]];
}
return params;
}; // 激活器
function Activitor(func) {
var obj = {};
func.apply(obj, setFuncParams(getFuncParams(func)));
return obj;
} // 定义新Service
function Service(abc, ghi) {
this.write = function () {
console.log(abc);
console.log(ghi);
}
} // 实例化Service并调用方法
var service = Activitor(Service);
service.write();
控制台成功打印!
JavaScript依赖注入的实现思路的更多相关文章
- Javascript——依赖注入
本人才学疏浅,本文只为抛砖引玉,欢迎各路大牛前来斧正,不胜感激! 如今各个框架都在模块化,连前端的javascript也不例外.每个模块负责一定的功能,模块与模块之间又有相互依赖,那么问题来了:jav ...
- yii 简单依赖注入
<?phpnamespace app\controllers;use Yii;use yii\di\Container;use yii\di\ServiceLocator;use yii\web ...
- NetCore+Dapper WebApi架构搭建(四):仓储的依赖注入
上一节我们讲到实体,仓储接口和仓储接口的实现需要遵循约定的命名规范,不仅是规范,而且为了依赖注入,现在我们实现仓储的依赖注入 在NetCore WebApi项目中新添加一个文件夹(Unit),当然你也 ...
- 3. abp依赖注入的分析.md
abp依赖注入的原理剖析 请先移步参考 [Abp vNext 源码分析] - 3. 依赖注入与拦截器 本文此篇文章的补充和完善. abp的依赖注入最后是通过IConventionalRegister接 ...
- 细数Javascript技术栈中的四种依赖注入
作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...
- [译]javascript中的依赖注入
前言 在上文介绍过控制反转之后,本来打算写篇文章介绍下控制反转的常见模式-依赖注入.在翻看资料的时候,发现了一篇好文Dependency injection in JavaScript,就不自己折腾了 ...
- JavaScript中依赖注入详细解析
计算机编程的世界其实就是一个将简单的部分不断抽象,并将这些抽象组织起来的过程.JavaScript也不例外,在我们使用JavaScript编写应用时,我们是不是都会使用到别人编写的代码,例如一些著名的 ...
- JavaScript里的依赖注入
JavaScript里的依赖注入 我喜欢引用这句话,“程序是对复杂性的管理”.计算机世界是一个巨大的抽象建筑群.我们简单的包装一些东西然后发布新工具,周而复始.现在思考下,你所使用的语言包括的一些内建 ...
- Javascript中的依赖注入
首先通过带参函数来定义一个Javascript函数,相当于C#中的一个类. var Person = function(firstname, lastname){ this.firstname = f ...
随机推荐
- AX7: HOW TO USE TABLE METHOD EXTENSION CLASS
To create new methods on a table without customize you should use the Table method extension class. ...
- MySQL的数据库,数据表,数据的操作
数据库简介 概念 什么是数据库?简单来说,数据库就是存储数据的"仓库", 但是,光有数据还不行,还要管理数据的工具,我们称之为数据库管理系统! 数据库系统 = 数据库管理系统 + ...
- PHP数据类型
在PHP中,一共支持8种数据类型:整型,浮点型,布尔型,字符串型,数组,对象,空类型(NULL),资源型 标量类型 int(integet)整数类型 整型数据:在内存中占4个字节,也就是32个bit位 ...
- MFC 自绘按钮 消息响应
单检测到按下消息时,发送一个消息 m_pParent->PostMessage(WM_COMMAND, IDC_BUTTON1); 然后再在消息映射里建立映射. ON_COMMAND(IDC_B ...
- 2016/9/25编写java实验报告时对synchronized(同步代码块)的一些感悟
通过此次实验,明白了多线程的设置和启动.synchronized代码块的用法.线程的优先级使用方法.知道了那几类资源是线程共享的. 我现在理解的多线程是:实例化一个继承了Thread类或实现了Runn ...
- MFC 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,已解决。
CKagulaCEdit是CEdit的一个继承类,m_edit的CKagulaCEdit类型的一个变量 调用的时候,是这样的: 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,问题如下: 这时 ...
- java使用jsch连接linux
由于项目需要使用java来linux进行管理,近一番查找,发现第三方jar包 jsch 可以轻松实现对linux的管理,(相关文档及例子请访问官网www.jcraft.com),故引进. 在网上搜索了 ...
- mysql中修改view的definer
我常用的工具是navicat,但是修改definer不能用工具,只能用命令行: 数据库迁移到其他服务器上,会报definer错误,修改view的definer方法如下(比如把definer改为本地的, ...
- NPOI操作Excel导入DataTable中
using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System.Data; using System.IO; using NPOI.X ...
- Hive集成HBase;安装pig
Hive集成HBase 配置 将hive的lib/中的HBase.jar包用实际安装的Hbase的jar包替换掉 cd /opt/hive/lib/ ls hbase-0.94.2* rm -rf ...