JavaScript中实现依赖注入的思路分享


Posted in Javascript onJanuary 15, 2015

如今各个框架都在模块化,连前端的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 相关文章推荐
js调用css属性写法
Sep 21 Javascript
js弹出层永远居中实现思路及代码
Nov 29 Javascript
关于javaScript注册click事件传递参数的不成功问题
Jul 18 Javascript
JQuery用户名校验的具体实现
Mar 18 Javascript
Bootstrap中的表单验证插件bootstrapValidator使用方法整理(推荐)
Jun 21 Javascript
js实现扫雷小程序的示例代码
Sep 27 Javascript
webpack多入口多出口的实现方法
Aug 17 Javascript
Vue组件之单向数据流的解决方法
Nov 10 Javascript
vue设计一个倒计时秒杀的组件详解
Apr 06 Javascript
Vuex模块化应用实践示例
Feb 03 Javascript
JavaScript中reduce()的5个基本用法示例
Jul 19 Javascript
解决vue-router 嵌套路由没反应的问题
Sep 22 Javascript
jquery实现textarea输入框限制字数的方法
Jan 15 #Javascript
28个常用JavaScript方法集锦
Jan 14 #Javascript
jquery单选框radio绑定click事件实现方法
Jan 14 #Javascript
jquery移动节点实例
Jan 14 #Javascript
jquery获取checkbox的值并post提交
Jan 14 #Javascript
js打造数组转json函数
Jan 14 #Javascript
使用jquery 简单实现下拉菜单
Jan 14 #Javascript
You might like
用PHP进行MySQL删除记录操作代码
2008/06/07 PHP
php排序算法(冒泡排序,快速排序)
2012/10/09 PHP
PHP按行读取、处理较大CSV文件的代码实例
2014/04/09 PHP
强制PHP命令行脚本单进程运行的方法
2014/04/15 PHP
Session 失效的原因汇总及解决丢失办法
2015/09/30 PHP
PHP registerXPathNamespace()函数讲解
2019/02/03 PHP
php设计模式之享元模式分析【星际争霸游戏案例】
2020/03/23 PHP
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
2009/04/24 Javascript
jquery select选中的一个小问题
2009/10/11 Javascript
js 弹出框只弹一次(二次修改之后的)
2013/11/26 Javascript
jquery 新建的元素事件绑定问题解决方案
2014/06/12 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
javascript实现的HashMap类代码
2014/06/27 Javascript
解决jquery插件:TypeError:$.browser is undefined报错的方法
2015/11/21 Javascript
VUEJS实战之构建基础并渲染出列表(1)
2016/06/13 Javascript
js实现按钮控制带有停顿效果的图片滚动
2016/08/30 Javascript
js改变透明度实现轮播图的算法
2020/08/24 Javascript
Angularjs使用ng-repeat中$even和$odd属性的注意事项
2016/12/31 Javascript
JS判断非空至少输入两个字符的简单实现方法
2017/06/23 Javascript
Angular 4.X开发实践中的踩坑小结
2017/07/04 Javascript
jQuery pjax 应用简单示例
2018/09/20 jQuery
微信小程序MUI导航栏透明渐变功能示例(通过改变rgba的a值实现)
2019/01/24 Javascript
[01:04:01]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第一场
2014/05/24 DOTA
和孩子一起学习python之变量命名规则
2018/05/27 Python
Python实现的redis分布式锁功能示例
2018/05/29 Python
详解Python下ftp上传文件linux服务器
2018/06/21 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
Pytorch中实现只导入部分模型参数的方式
2020/01/02 Python
keras的三种模型实现与区别说明
2020/07/03 Python
详解pyqt5的UI中嵌入matplotlib图形并实时刷新(挖坑和填坑)
2020/08/07 Python
微软香港官网及网上商店:Microsoft HK
2016/09/01 全球购物
美国综合购物商城:UnbeatableSale.com
2018/11/28 全球购物
单位领导证婚词
2014/01/14 职场文书
公司借款担保书
2015/09/22 职场文书
关于PostgreSQL JSONB的匹配和交集问题
2021/09/14 PostgreSQL
Win10 最新稳定版本 21H2开始推送
2022/04/19 数码科技