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 相关文章推荐
兼容ie、firefox的图片自动缩放的css跟js代码分享
Jan 21 Javascript
jQuery实现带滚动线条导航效果的方法
Jan 30 Javascript
jQuery实现平滑滚动的标签分栏切换效果
Aug 28 Javascript
JavaScript知识点整理
Dec 09 Javascript
ES6新特性二:Iterator(遍历器)和for-of循环详解
Apr 20 Javascript
JS实现为动态创建的元素添加事件操作示例
Mar 17 Javascript
解决淘宝cnpm 安装后cnpm不是内部或外部命令的问题
May 17 Javascript
浅谈小程序 setData学问多
Feb 20 Javascript
ajax跨域访问遇到的问题及解决方案
May 23 Javascript
微信小程序加载机制及运行机制图解
Nov 27 Javascript
Vue实现点击当前元素以外的地方隐藏当前元素(实现思路)
Dec 04 Javascript
js实现随机点名器精简版
Jun 29 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
smarty section简介与用法分析
2008/10/03 PHP
php做下载文件的实现代码及文件名中乱码解决方法
2011/02/03 PHP
两级联动select刷新后其值保持不变的实现方法
2014/01/27 PHP
php 无限级分类,超级简单的无限级分类,支持输出树状图
2014/06/29 PHP
php使用ZipArchive函数实现文件的压缩与解压缩
2015/10/27 PHP
浅谈PHP中关于foreach使用引用变量的坑
2016/11/14 PHP
php json相关函数用法示例
2017/03/28 PHP
php获取ip及网址的简单方法(必看)
2017/04/01 PHP
仿服务器端脚本方式的JS模板实现方法
2007/04/27 Javascript
JS修改css样式style浅谈
2013/05/06 Javascript
浅析JavaScript中浏览器的兼容问题
2016/04/19 Javascript
特殊日期提示功能的实现方法
2016/06/16 Javascript
Node.js实现兼容IE789的文件上传进度条
2016/09/02 Javascript
微信小程序 触控事件详细介绍
2016/10/17 Javascript
JS表单验证方法实例小结【电话、身份证号、Email、中文、特殊字符、身份证号等】
2017/02/14 Javascript
vue项目中使用axios上传图片等文件操作
2017/11/02 Javascript
使用vue官方提供的模板vue-cli搭建一个helloWorld案例分析
2018/01/16 Javascript
Vue侦测相关api的实现方法
2019/05/22 Javascript
如何基于JS截获动态代码
2019/12/25 Javascript
vue如何使用rem适配
2021/02/06 Vue.js
python实现人脸识别经典算法(一) 特征脸法
2018/03/13 Python
使用TensorFlow搭建一个全连接神经网络教程
2020/02/06 Python
利用python中的matplotlib打印混淆矩阵实例
2020/06/16 Python
pytorch 计算ConvTranspose1d输出特征大小方式
2020/06/23 Python
Python实现七个基本算法的实例代码
2020/10/08 Python
Python中读取文件名中的数字的实例详解
2020/12/25 Python
python工具——Mimesis的简单使用教程
2021/01/16 Python
纯css3制作煽动翅膀的蝴蝶的示例
2018/04/23 HTML / CSS
高中的自我鉴定
2013/12/16 职场文书
预备党员入党思想汇报
2014/01/04 职场文书
计生办班子群众路线教育实践活动个人对照检查材料思想汇报
2014/10/04 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
2014年财政局工作总结
2014/12/09 职场文书
HTML5 新增内容和 API详解
2021/11/17 HTML / CSS
PC版《死亡搁浅导剪版》现已发售 展开全新的探险
2022/04/03 其他游戏
MySQL数据库 安全管理
2022/05/06 MySQL