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 相关文章推荐
jQuery判断元素是否是隐藏的代码
Apr 24 Javascript
js实现从中间开始往上下展开网页窗口的方法
Mar 02 Javascript
jQuery链式调用与show知识浅析
May 11 Javascript
js模式化窗口问题![window.dialogArguments]
Oct 30 Javascript
Kindeditor单独调用单图上传增加预览功能的实例
Jul 31 Javascript
angularjs实现天气预报功能
Jun 16 Javascript
Node Puppeteer图像识别实现百度指数爬虫的示例
Feb 22 Javascript
vue前后分离调起微信支付
Jul 29 Javascript
微信小程序图片加载失败时替换为默认图片的方法
Dec 09 Javascript
基于vue中的scoped坑点解说
Sep 04 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
Nov 16 Javascript
js动态添加带圆圈序号列表的实例代码
Feb 18 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
十大催泪虐心动漫,你能坚持看到第几部?
2020/03/04 日漫
php设计模式之命令模式使用示例
2014/03/02 PHP
PHP中如何判断exec函数执行成功?
2016/08/04 PHP
php中Redis的应用--消息传递
2017/03/28 PHP
php简单生成一组与多组随机字符串的方法
2017/05/09 PHP
php利用ob_start()清除输出和选择性输出的方法
2018/01/18 PHP
PHP删除数组中特定元素的两种方法
2019/02/28 PHP
laravel 验证错误信息到 blade模板的方法
2019/09/29 PHP
图片格式的JavaScript和CSS速查手册
2007/08/20 Javascript
jQuery之按钮组件的深入解析
2013/06/19 Javascript
jQuery中animate用法实例分析
2015/03/09 Javascript
jQuery三级下拉列表导航菜单代码分享
2020/04/15 Javascript
jQuery Tags Input Plugin(添加/删除标签插件)详解
2016/06/20 Javascript
Javascript中call,apply,bind方法的详解与总结
2016/12/12 Javascript
jQuery实现简单的抽奖游戏
2017/05/05 jQuery
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
python进阶教程之函数对象(函数也是对象)
2014/08/30 Python
详解Python中的array数组模块相关使用
2016/07/05 Python
django将图片上传数据库后在前端显式的方法
2018/05/25 Python
Python实现的爬取网易动态评论操作示例
2018/06/06 Python
解决python selenium3启动不了firefox的问题
2018/10/13 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
2019/07/04 Python
在VS2017中用C#调用python脚本的实现
2019/07/31 Python
Python 一键获取百度网盘提取码的方法
2019/08/01 Python
python基础 range的用法解析
2019/08/23 Python
Python实现像awk一样分割字符串
2020/09/15 Python
Python+MySQL随机试卷及答案生成程序的示例代码
2021/02/01 Python
伦敦所有西区剧院演出官方票务代理:Theatre Tickets Direct
2017/05/26 全球购物
地理科学专业毕业生求职信
2013/10/15 职场文书
古汉语文学求职信范文
2014/03/16 职场文书
村主任群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
大学生实训报告总结
2014/11/05 职场文书
2015年档案室工作总结
2015/05/23 职场文书
工作转正自我鉴定范文
2019/06/21 职场文书
详解JavaScript的计时器和按钮效果设置
2022/02/18 Javascript
python playwrigh框架入门安装使用
2022/07/23 Python