如今各个框架都在模块化,连前端的javascript也不例外。每个模块负责一定的功能,模块与模块之间又有相互依赖,那么问题来了:javascript的依赖注入如何实现?(javascript的依赖注入,各大框架都有相应的实现,这里只学习实现思路)

如下需求:

假设已经有定义好的服务模块Key-Value集合,func为添加的新服务,参数列表为服务依赖项。

  1. var services = { abc : 123, def : 456, ghi : 789 }; // 假设已定义好某些Service
  2. function Service(abc, ghi){
  3. this.write = function(){
  4. console.log(abc);
  5. console.log(ghi);
  6. }
  7. }
  8. function Activitor(func){
  9. var obj;
  10. // 实现
  11. return obj;
  12. }

解决思路:

通过某种机制(反射?),取出该func定义的参数列表,并一一赋值。然后再通过某种机制(Activitor?),实例化该func。

解决方案:

一、获取func的参数列表:

如何获取参数列表呢?我首先想到的是反射机制。那javascript里面有没有反射呢?应该有吧,我目前只知道使用eval(str)函数,但貌 似并没有获取参数列表的相关实现。再看func.arguments定义,此属性只在调用func并传递参数时才有效,也不能满足需求。

那能不能通过处理func.toString()后的字符串获取参数列表呢?

上手试试吧:

  1. function getFuncParams(func) {
  2. var matches = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m);
  3. if (matches && matches.length > 1)
  4. return matches[1].replace(/\s*/, '').split(',');
  5. return [];
  6. };

至此获得func参数列表数组。

二、根据参数列表寻找依赖:

得到了参数列表,即得到了依赖列表,将依赖项作为参数传入也就很简单了。

  1. var params = getFuncParams(func);
  2. or (var i in params) {
  3. params[i] = services[params[i]];

三、传递依赖项参数并实例化:

我们知道,javascript里面有func.constructor有call(thisArg,[arg[,arg,[arg, […]]]])和apply(thisArg,args…)两个函数,都可以实现实例化func操作。其中call函数第一个参数为this指针,剩余为 参数列表,这个适合在已知func参数列表的情况下使用,不能满足我的需求。再看第二个apply函数,第一个参数也为this指针,第二个参数为参数数 组,其在调用时会自动为func的参数列表一一赋值,正好满足我的需求。

代码大概如下:

  1. function Activitor(func){
  2. var obj = {};
  3. func.apply(obj, params);
  4. return obj;
  5. }

至此我们能够创建该func的实例,并传递该func需要的参数。

四、打印测试一下吧:

完整代码:

  1. var
  2. // 假设已定义好某些Service
  3. services = { abc: 123, def: 456, ghi: 789 },
  4. // 获取func的参数列表(依赖列表)
  5. getFuncParams = function (func) {
  6. var matches = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m);
  7. if (matches && matches.length > 1)
  8. return matches[1].replace(/\s+/, '').split(',');
  9. return [];
  10. },
  11. // 根据参数列表(依赖列表)填充参数(依赖项)
  12. setFuncParams = function (params) {
  13. for (var i in params) {
  14. params[i] = services[params[i]];
  15. }
  16. return params;
  17. };
  18. // 激活器
  19. function Activitor(func) {
  20. var obj = {};
  21. func.apply(obj, setFuncParams(getFuncParams(func)));
  22. return obj;
  23. }
  24. // 定义新Service
  25. function Service(abc, ghi) {
  26. this.write = function () {
  27. console.log(abc);
  28. console.log(ghi);
  29. }
  30. }
  31. // 实例化Service并调用方法
  32. var service = Activitor(Service);
  33. service.write();

控制台成功打印!

来源:51CTO

JavaScript依赖注入的实现思路相关推荐

  1. Spring: 依赖注入的实现

    上一篇中已经实现了通过IOC容器创建BEAN并管理, 在实际开发中BEAN之间的依赖是不可避免的. 例: 用户模块依赖于通用模块, 订单模块同时依赖于用户模块和通用模块等等. Spring提供了依赖注 ...

  2. DI 依赖注入实现原理

    深度理解依赖注入(Dependence Injection) 前面的话:提到依赖注入,大家都会想到老马那篇经典的文章.其实,本文就是相当于对那篇文章的解读.所以,如果您对原文已经有了非常深刻的理解,完 ...

  3. 框架依赖注入和普通依赖注入_依赖注入快速入门:它是什么,以及何时使用它...

    框架依赖注入和普通依赖注入 by Bhavya Karia 通过Bhavya Karia 介绍 (Introduction) In software engineering, dependency i ...

  4. 最全的 Spring 依赖注入方式,你都会了吗?

    欢迎关注方志朋的博客,回复"666"获面试宝典 前言 Spring 正如其名字,给开发者带来了春天,Spring 是为解决企业级应用开发的复杂性而设计的一款框架,其设计理念就是:简 ...

  5. android组件浮动在activity上_Jetpack Hilt 依赖注入框架上手指南

    code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群 作者:LvKang-insist 链接:https://juejin.im/post/5efdff9d6fb9a07e ...

  6. 如何理解依赖注入(DI)

    什么是依赖注入(Dependency Injection) 依赖倒置原则:高层模块不应该依赖于低层模块,两个都应该依赖于抽象(接口). 依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下层代码 ...

  7. php程序设计依赖注入_PHP控制反转和依赖注入

    [TOC] PHP和依赖注入 理论知识 要了解控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想:依赖倒置原则(Dependency Inversio ...

  8. AngularJs 基础教程 —— 依赖注入

    为什么80%的码农都做不了架构师?>>>    本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:AngularJs 基础教程 -- 依赖注入 AngularJS 依赖注 ...

  9. Spring核心——Bean的依赖注入

    依赖注入 在设计模式与IoC这篇文章中,介绍了Spring基础的三大支柱的两项内容--IoC.Bean.本篇将继续围绕着Bean的创建时的注入方式来介绍Spring的核心思想与设计模式. 天底下所有面 ...

最新文章

  1. 《Oracle系列》:oracle job详解
  2. 执行SQL-获取缓存
  3. get占位符传多个参数_mybatis多个参数(不使用@param注解情况下),sql参数占位符正确写法...
  4. xss漏洞php注射实战,利用XSS渗透DISCUZ 6.1.0实战
  5. Crashlytics功能集成
  6. Linux服务器系统备份还原
  7. POJ 1037 DP
  8. Green Plum测试报告
  9. 云课堂智慧职教网页版登录入口_云课堂智慧职教网页版登录入口-云课堂智慧职教app官网版下载-XP软件园...
  10. FRM考试时间明细,FRM考试全方面日程表
  11. window10华硕计算机主板VT,华硕主板怎么开启vt 【设置步骤】
  12. web网页常见特效3——轮播图
  13. 【年终总结】—此生平凡,终不简单
  14. windows编程之WM_MENUSELECT消息
  15. Xcode MacOS与clang c++版本关系
  16. java 庖丁解牛api_重磅|庖丁解牛之——Flutter for Web
  17. Buffon投针实验
  18. c语言des算法实验报告,c语言实现des算法des加密算法实验报告
  19. android 点击震动,Android 使用Vibrator服务实现点击按钮带有震动效果
  20. 经典智力题:经理年龄问题

热门文章

  1. [Bzoj]5343: [Ctsc2018]混合果汁
  2. (C/C++) Link List - C++ 版本
  3. 将Spring源码转换为工程 + 导入Eclipse时缺失jar包
  4. 将数字n转换为字符串并保存到s中
  5. 范式的数据库具体解释
  6. 服务:OracleDBConsoleorcl [Agent process exited abnormally during initialization]
  7. Javascript学习笔记8——用JSON做原型
  8. .net中C#代码与javaScript函数的相互调用问题
  9. 求两等长升序序列的中位数
  10. centos 7 源码方式安装mysql5.6