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 相关文章推荐
在textarea文本域中显示HTML代码的方法
Mar 06 Javascript
javascript 对象定义方法 简单易学
Mar 22 Javascript
JS DOM 操作实现代码
Aug 01 Javascript
js中匿名函数的N种写法
Sep 08 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
Apr 12 Javascript
jquery实现Li滚动时滚动条自动添加样式的方法
Aug 10 Javascript
Bootstrap每天必学之导航条
Nov 27 Javascript
Javascript生成带参数的二维码示例
Oct 10 Javascript
JS继承与闭包及JS实现继承的三种方式
Oct 15 Javascript
vue使用vue-i18n实现国际化的实现代码
Apr 08 Javascript
Bootstrap Table 双击、单击行获取该行及全表内容
Aug 31 Javascript
判断iOS、Android以及PC端的示例代码
Nov 15 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
输出控制类
2006/10/09 PHP
建立动态的WML站点(二)
2006/10/09 PHP
转换中文日期的PHP程序
2006/10/09 PHP
php下网站防IP攻击代码,超级实用
2010/10/24 PHP
Mootools 1.2教程 Tooltips
2009/09/15 Javascript
js对象数组按属性快速排序
2011/01/31 Javascript
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
javascript判断非数字的简单例子
2013/07/18 Javascript
关于删除时的提示处理(确定删除吗)
2013/11/03 Javascript
js与运算符和或运算符的妙用
2014/02/14 Javascript
关于延迟加载JavaScript
2015/05/05 Javascript
JavaScript组件开发完整示例
2015/12/15 Javascript
AngularJS实现Input格式化的方法
2016/11/07 Javascript
nodejs制作爬虫实现批量下载图片
2017/05/19 NodeJs
浅谈es6语法 (Proxy和Reflect的对比)
2017/10/24 Javascript
VUE+elementui面包屑实现动态路由详解
2019/11/04 Javascript
基于python的汉字转GBK码实现代码
2012/02/19 Python
python中getattr函数使用方法 getattr实现工厂模式
2014/01/20 Python
python通过socket查询whois的方法
2015/07/18 Python
python直接访问私有属性的简单方法
2016/07/25 Python
Python标准库06之子进程 (subprocess包) 详解
2016/12/07 Python
Python实现12306火车票抢票系统
2019/07/04 Python
pandas 对group进行聚合的例子
2019/12/27 Python
Python任务调度模块APScheduler使用
2020/04/15 Python
Python OrderedDict字典排序方法详解
2020/05/21 Python
详解HTML5常用的语义化标签
2019/09/27 HTML / CSS
英国最受欢迎的手表网站:Watch Shop
2016/10/21 全球购物
汽车销售求职自荐信
2013/10/01 职场文书
文史专业毕业生自荐信
2013/11/17 职场文书
社团文化节策划书
2014/02/01 职场文书
安全保卫工作竞聘材料
2014/08/25 职场文书
保密工作整改报告
2014/11/06 职场文书
2015年村计划生育工作总结
2015/04/28 职场文书
不同意离婚代理词
2015/05/23 职场文书
考试后的感想
2015/08/07 职场文书
Golang并发操作中常见的读写锁详析
2021/08/30 Golang