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 相关文章推荐
javascript 动态添加表格行
Jun 22 Javascript
Prototype源码浅析 String部分(二)
Jan 16 Javascript
javascript移出节点removeChild()使用介绍
Apr 03 Javascript
JavaScript 模块化编程(笔记)
Apr 08 Javascript
JavaScript中实现Map的示例代码
Sep 09 Javascript
谈谈js中的prototype及prototype属性解释和常用方法
Nov 25 Javascript
Javascript从数组中随机取出不同元素的两种方法
Sep 22 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
Aug 22 Javascript
JQuery中queue方法用法示例
Jan 31 jQuery
vue 使用鼠标滚动加载数据的例子
Oct 31 Javascript
基于JavaScript实现大文件上传后端代码实例
Aug 18 Javascript
jquery插件实现图片悬浮
Apr 16 jQuery
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
dede3.1分页文字采集过滤规则详说(图文教程)续二
2007/04/03 PHP
php强制下载类型的实现代码
2011/04/21 PHP
使用PHP导出Word文档的原理和实例
2013/10/21 PHP
PHP向socket服务器收发数据的方法
2015/01/24 PHP
Laravel实现构造函数自动依赖注入的方法
2016/03/16 PHP
如何在Web页面上直接打开、编辑、创建Office文档
2007/03/12 Javascript
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
javascript实现的字符串与十六进制表示字符串相互转换方法
2015/07/17 Javascript
window.onload绑定多个事件的两种解决方案
2016/05/15 Javascript
jquery简单插件制作(fn.extend)完整实例
2016/05/24 Javascript
webpack中引用jquery的简单实现
2016/06/08 Javascript
详解基于 axios 的 Vue 项目 http 请求优化
2017/09/04 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
2018/04/08 Javascript
JavaScript控制浏览器全屏显示简单示例
2018/07/05 Javascript
详解VUE单页应用骨架屏方案
2019/01/17 Javascript
Vue SPA 首屏优化方案
2021/02/26 Vue.js
[04:07]显微镜下的DOTA2第八期——英雄复活动作
2014/06/24 DOTA
Python中scatter函数参数及用法详解
2017/11/08 Python
python使用jieba实现中文分词去停用词方法示例
2018/03/11 Python
Python面向对象之静态属性、类方法与静态方法分析
2018/08/24 Python
Python类的继承用法示例
2019/01/31 Python
详解python执行shell脚本创建用户及相关操作
2019/04/11 Python
Python中的pathlib.Path为什么不继承str详解
2019/06/23 Python
Python中__repr__和__str__区别详解
2019/11/07 Python
python中如何使用insert函数
2020/01/09 Python
python新手学习可变和不可变对象
2020/06/11 Python
python 检测图片是否有马赛克
2020/12/01 Python
HTML5本地存储和本地数据库实例详解
2017/09/05 HTML / CSS
日本网路线上商品代购服务:转送JAPAN
2016/08/05 全球购物
思想汇报格式
2014/01/05 职场文书
《池塘边的叫声》教学反思
2014/04/12 职场文书
11.9消防日宣传标语
2014/10/08 职场文书
群众路线教育实践活动总结
2014/10/30 职场文书
2015年个人剖析材料范文
2014/12/29 职场文书
Java新手教程之ArrayList的基本使用
2021/06/20 Java/Android