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 相关文章推荐
超级退弹代码
Jul 07 Javascript
浅谈JavaScript中Date(日期对象),Math对象
Feb 05 Javascript
JavaScript DOM进阶方法
Apr 13 Javascript
javascript字符串与数组转换汇总
May 26 Javascript
js改变style样式和css样式的简单实例
Jun 28 Javascript
vue2.0实战之基础入门(1)
Mar 27 Javascript
javascript深拷贝的原理与实现方法分析
Apr 10 Javascript
使用JS在浏览器中判断当前网络连接状态的几种方法
May 05 Javascript
JavaScript创建对象_动力节点Java学院整理
Jun 27 Javascript
vue组件name的作用小结
May 23 Javascript
微信小程序自定义弹窗实现详解(可通用)
Jul 04 Javascript
解决layui动态添加的元素click等事件触发不了的问题
Sep 20 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四舍五入精确小数位及取整
2014/01/14 PHP
使用PHP生成二维码的两种方法(带logo图像)
2014/03/14 PHP
php根据年月获取季度的方法
2014/03/31 PHP
php获取网页请求状态程序示例
2014/06/17 PHP
在Windows XP下安装Apache+MySQL+PHP环境
2015/02/22 PHP
PHP PDOStatement::bindColumn讲解
2019/01/30 PHP
基于jsTree的无限级树JSON数据的转换代码
2010/07/27 Javascript
jQuery数组处理代码详解(含实例演示)
2012/02/03 Javascript
js判断上传文件的类型和大小示例代码
2013/10/18 Javascript
探讨js字符串数组拼接的性能问题
2014/10/11 Javascript
JsRender实用入门教程
2014/10/31 Javascript
javascript顺序加载图片的方法
2015/07/18 Javascript
基于对象合并功能的实现示例
2017/10/10 Javascript
详解Vue demo实现商品列表的展示
2019/05/07 Javascript
vue element-ui el-date-picker限制选择时间为当天之前的代码
2019/11/07 Javascript
vue 动态设置img的src地址无效,npm run build 后找不到文件的解决
2020/07/26 Javascript
python实现简单遗传算法
2018/03/19 Python
python操作excel的方法
2018/08/16 Python
提升Python程序性能的7个习惯
2019/04/14 Python
python super()函数的基本使用
2020/09/10 Python
CSS3实现红包抖动效果
2020/12/23 HTML / CSS
New Balance英国官方网站:始于1906年,百年慢跑品牌
2016/12/07 全球购物
DC Shoes澳大利亚官方网上商店:购买DC鞋子
2019/10/25 全球购物
资生堂英国官网:Shiseido英国
2020/12/30 全球购物
Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?
2015/08/04 面试题
家电业务员岗位职责
2014/03/10 职场文书
求职简历自荐信
2014/06/18 职场文书
电大奖学金获奖感言
2014/08/14 职场文书
公证委托书格式
2014/09/13 职场文书
防汛工作情况汇报
2014/10/28 职场文书
工商行政处罚决定书
2015/06/24 职场文书
美容院员工规章制度
2015/08/05 职场文书
超外差式晶体管收音机的组装与统调
2021/04/22 无线电
Python3中最常用的5种线程锁实例总结
2021/07/07 Python
python turtle绘制多边形和跳跃和改变速度特效
2022/03/16 Python
Android 中的类文件和类加载器详情
2022/06/05 Java/Android