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 相关文章推荐
JavaScript实现动态增加文件域表单
Feb 12 Javascript
利用JS延迟加载百度分享代码,提高网页速度
Jul 01 Javascript
JavaScript实现的encode64加密算法实例分析
Apr 15 Javascript
学习JavaScript设计模式之策略模式
Jan 12 Javascript
jQuery插件制作的实例教程
May 16 Javascript
jQuery Easyui快速入门教程
Aug 21 Javascript
JS判断两个对象内容是否相等的方法示例
Apr 10 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
Mar 08 Javascript
react实现移动端下拉菜单的示例代码
Jan 16 Javascript
JS原型对象操作实例分析
Jun 06 Javascript
浅谈在vue-cli3项目中解决动态引入图片img404的问题
Aug 04 Javascript
详解vue v-model
Aug 31 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
评分9.0以上的动画电影,剧情除了经典还很燃
2020/03/04 日漫
一个php作的文本留言本的例子(一)
2006/10/09 PHP
深入了解PHP类Class的概念
2012/06/14 PHP
Yii模型操作之criteria查找数据库的方法
2016/07/15 PHP
PHP代码覆盖率统计详解
2020/07/22 PHP
jQuery入门问答 整理的几个常见的初学者问题
2010/02/22 Javascript
jQuery布局插件UI Layout简介及使用方法
2013/04/03 Javascript
鼠标移到导航当前位置的LI变色处于选中状态
2013/08/23 Javascript
js中arguments,caller,callee,apply的用法小结
2014/01/28 Javascript
一些老手都不一定知道的JavaScript技巧
2014/05/06 Javascript
js获取当前页面的url网址信息
2014/06/12 Javascript
浅谈JS闭包中的循环绑定处理程序
2014/11/09 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
每日十条JavaScript经验技巧(二)
2016/06/23 Javascript
在线引用最新jquery文件的实现方法
2016/08/26 Javascript
JavaScript实现DOM对象选择器
2016/09/24 Javascript
原生JS改变透明度实现轮播效果
2017/03/24 Javascript
JavaScript中splice与slice的区别
2017/05/09 Javascript
bootstrap datepicker插件默认英文修改为中文
2017/07/28 Javascript
JavaScript中防止微信浏览器被整体拖动的方法
2017/08/25 Javascript
JS实现显示当前日期的实例代码
2018/07/03 Javascript
详解Vue的常用指令v-if, v-for, v-show,v-else, v-bind, v-on
2018/10/12 Javascript
javascript简单实现深浅拷贝过程详解
2019/10/08 Javascript
浅谈nuxtjs校验登录中间件和混入(mixin)
2020/11/06 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
Python利用matplotlib生成图片背景及图例透明的效果
2017/04/27 Python
python遍历一个目录,输出所有的文件名的实例
2018/04/23 Python
python动态进度条的实现代码
2019/07/03 Python
别名指示符是什么
2012/10/08 面试题
毕业生个人求职信范例分享
2013/12/17 职场文书
《雷雨》教学反思
2014/02/20 职场文书
《去年的树》教学反思
2014/04/11 职场文书
爱国演讲稿500字
2014/05/04 职场文书
个人合伙协议书范本
2014/10/14 职场文书
广告公司文案策划岗位职责
2015/04/14 职场文书
委托开发合同书(标准版)
2019/08/07 职场文书