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实现打开本地文件或文件夹
Mar 09 Javascript
JavaScript基本概念初级讲解论坛贴的学习记录
Feb 22 Javascript
SlideView 图片滑动(扩展/收缩)展示效果
Aug 01 Javascript
Array栈方法和队列方法的特点说明
Jan 24 Javascript
JavaScript函数模式详解
Nov 07 Javascript
Javascript实现Array和String互转换的方法
Dec 21 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
Feb 25 Javascript
BootStrap便签页的简单应用
Jan 06 Javascript
javascript编程实现栈的方法详解【经典数据结构】
Apr 11 Javascript
JS中去掉array中重复元素的方法
May 26 Javascript
使用cookie绕过验证码登录的实现代码
Oct 12 Javascript
vue实现节点增删改功能
Sep 26 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猜单词游戏
2015/09/29 PHP
PHP依赖注入原理与用法分析
2018/08/21 PHP
PHP扩展类型及安装方式解析
2020/04/27 PHP
jQuery实现原理的模拟代码 -6 代码下载
2010/08/16 Javascript
JavaScript中的排序算法代码
2011/02/22 Javascript
Jquery为单选框checkbox绑定单击click事件
2012/12/18 Javascript
js动态添加表格数据使用insertRow和insertCell实现
2014/05/22 Javascript
JavaScript中的alert()函数使用技巧详解
2014/12/29 Javascript
javascript将异步校验表单改写为同步表单
2015/01/27 Javascript
js实现固定显示区域内自动缩放图片的方法
2015/07/18 Javascript
深入探讨前端框架react
2015/12/09 Javascript
bootstrap日历插件datetimepicker使用方法
2016/12/14 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
2017/07/30 Javascript
Nodejs实现的操作MongoDB数据库功能完整示例
2019/02/02 NodeJs
layui select 禁止点击的实现方法
2019/09/05 Javascript
vue2路由基本用法实例分析
2020/03/06 Javascript
[15:57]教你分分钟做大人:斧王
2014/10/30 DOTA
用Python和MD5实现网站挂马检测程序
2014/03/13 Python
python实现八大排序算法(2)
2017/09/14 Python
Python元组及文件核心对象类型详解
2018/02/11 Python
Python使用xlwt模块操作Excel的方法详解
2018/03/27 Python
Python学习笔记之抓取某只基金历史净值数据实战案例
2019/06/03 Python
python添加菜单图文讲解
2019/06/04 Python
Python识别快递条形码及Tesseract-OCR使用详解
2019/07/15 Python
tensorflow入门:TFRecordDataset变长数据的batch读取详解
2020/01/20 Python
python 已知一个字符,在一个list中找出近似值或相似值实现模糊匹配
2020/02/29 Python
html5构建触屏网站之网站尺寸探讨
2013/01/07 HTML / CSS
HTML5中的进度条progress元素简介及兼容性处理
2016/06/02 HTML / CSS
迪梵英国官方网站:Darphin英国
2017/12/06 全球购物
Coggles美国/加拿大:高级国际时装零售商
2018/10/23 全球购物
命名空间(namespace)和程序集(Assembly)有什么区别
2015/09/25 面试题
2014年最新版离婚协议书范本
2014/11/25 职场文书
资料员岗位职责
2015/02/10 职场文书
商超业务员岗位职责
2015/02/13 职场文书
实习证明格式范文
2015/06/16 职场文书
党风廉政承诺书2016
2016/03/25 职场文书