JavaScript反射与依赖注入实例详解


Posted in Javascript onMay 29, 2018

本文实例讲述了JavaScript反射与依赖注入。分享给大家供大家参考,具体如下:

对于javascript中的反射的理解,一直都是认为,利用数组对回调函数进行保存,之后在适当的时刻利用call或是apply 方法,对回调进行调用即可,一般如下操作:

首先定义两个方法:

var service = function() {
  return { name: 'Service' };
}
var router = function() {
  return { name: 'Router' };
}

我们有另一个函数需要用到这两个模块。

var doSomething = function(other) {
  var s = service();
  var r = router();
};

当然,我们希望能够能够使用依赖注入的方式去做,把该控制权交给计算机去做,而不是人为的去调用如下:

var doSomething = injector.resolve('router,,service', function(a, b, c) {
  expect(a().name).to.be('Router');
  expect(b).to.be('Other');
  expect(c().name).to.be('Service');
});
doSomething("Other");

那么我们可以造出一个反射方法如下:

var injector ={
    dependencies: {},
    register: function(key, value) {
      this.dependencies[key] = value;
    },
    resolve:function(deps, func, scope) {
      var args = [];
      for(var i=0; i<deps.length, d=deps[i]; i++) {
        if(this.dependencies[d]) {
          args.push(this.dependencies[d]);
        } else {
          throw new Error('Can\'t resolve ' + d);
        }
      }
      return function() {
        func.apply(scope || {}, args.concat(Array.prototype.slice.call(arguments, 0)));
      }
    }
};

如上代码,dependencies 用来保存回调函数集合,resolve用来调用。

这也算是一个比较成熟ok的想法。

但是依旧存在几点问题:

1 resolve 在进行调用时,deps参数列表顺序必须保持一致。

2 这一点有点牵强,但是也算。在调用时,需要再一次的输入形参,而不能直接调用。

那么为了解决以上问题,给出以下解决方案:

var injector ={
    dependencies: {},
    register: function(key, value) {
      this.dependencies[key] = value;
    },
    resolve: function() {
      var func, deps, scope, args = [], self = this;
      if(typeof arguments[0] === 'string') {
        func = arguments[1];
        deps = arguments[0].replace(/ /g, '').split(',');
        scope = arguments[2] || {};
      } else {
        func = arguments[0];
        deps = func.toString().match(/^function\s*[^]*\(\s*([^]*\(\s*([^]*)\)/m)[1].replace(/ /g, '').split(',');
        scope = arguments[1] || {};
      }
      return function() {
        var a = Array.prototype.slice.call(arguments, 0);
        for(var i=0; i<deps.length; i++) {
          var d = deps[i];
          args.push(self.dependencies[d] && d != '' ? self.dependencies[d] : a.shift());
        }
        func.apply(scope || {}, args);
      }
    }
};

利用正则对代码进行解析,解析出function 列表参数,再进行一一自动匹配传值,那么即可解决,顺序必须一直问题,当然这也是当然最热mvvm框架AngularJs采取的方式。

调用方式可以如下:

injector.resolve(['service,,router', function(service, router) {
}]);

你可能注意到在第一个参数后面有两个逗号——注意

这不是笔误。空值实际上代表“Other”参数(占位符)。这显示了我们是如何控制参数顺序的。

最后还有一种方式,直接注入scope ,也就是直接注入作用域,那么作用域被注入,也就不存在上述的传参顺序问题

因为不在需要传递参数,直接可以从作用域中访问到。

var injector = {
  dependencies: {},
  register: function(key, value) {
    this.dependencies[key] = value;
  },
  resolve: function(deps, func, scope) {
    var args = [];
    scope = scope || {};
    for(var i=0; i<deps.length, d=deps[i]; i++) {
      if(this.dependencies[d]) {
        scope[d] = this.dependencies[d];
      } else {
        throw new Error('Can\'t resolve ' + d);
      }
    }
    return function() {
      func.apply(scope || {}, Array.prototype.slice.call(arguments, 0));
    }
  }
}
var doSomething = injector.resolve(['service', 'router'], function(other) {
  expect(this.service().name).to.be('Service');
  expect(this.router().name).to.be('Router');
  expect(other).to.be('Other');
});
doSomething("Other");

javascript反射依赖注入新的理解,记录之,谨防忘记.

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript获取当前ip的代码
May 10 Javascript
jQuery EasyUI API 中文文档 - Spinner微调器使用
Oct 21 Javascript
js 3种归并操作的实例代码
Oct 30 Javascript
javascript中不等于的代码是什么怎么写
Dec 29 Javascript
EasyUI实现第二层弹出框的方法
Mar 01 Javascript
利用python分析access日志的方法
Oct 26 Javascript
jQuery Easyui加载表格出错时在表格中间显示自定义的提示内容
Dec 08 Javascript
微信小程序form表单组件示例代码
Jul 15 Javascript
详解Axios统一错误处理与后置
Sep 26 Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
Apr 14 Javascript
Vue实现下拉加载更多
May 09 Vue.js
JavaScript 数组去重详解
Sep 15 Javascript
使用webpack3.0配置webpack-dev-server教程
May 29 #Javascript
vuejs 切换导航条高亮(路由菜单高亮)的方法示例
May 29 #Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
May 29 #Javascript
Vue 全局loading组件实例详解
May 29 #Javascript
详解vue-cli 本地开发mock数据使用方法
May 29 #Javascript
详解vue-cli项目中怎么使用mock数据
May 29 #Javascript
js统计页面上每个标签的数量实例代码
May 29 #Javascript
You might like
PHP脚本中include文件出错解决方法
2008/11/20 PHP
微盾PHP脚本加密专家php解密算法
2020/09/13 PHP
UCenter 批量添加用户的php代码
2012/07/17 PHP
php字符比较函数similar_text、strnatcmp与strcasecmp用法分析
2014/11/18 PHP
Laravel5.7 数据库操作迁移的实现方法
2019/04/12 PHP
Yii框架中使用PHPExcel的方法分析
2019/07/25 PHP
js实现身份证号码验证的简单实例
2014/02/19 Javascript
extjs 时间范围选择自动判断的实现代码
2014/06/24 Javascript
JS创建类和对象的两种不同方式
2014/08/08 Javascript
浅谈javascript中this在事件中的应用
2015/02/15 Javascript
详解nodejs与javascript中的aes加密
2016/05/22 NodeJs
javascript如何创建对象
2016/08/29 Javascript
jquery——九宫格大转盘抽奖实例
2017/01/16 Javascript
vue中axios解决跨域问题和拦截器的使用方法
2018/03/07 Javascript
详解Vue之计算属性
2020/06/20 Javascript
[01:03:37]Secret vs VGJ.S Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
详解python单例模式与metaclass
2016/01/15 Python
Python中数组,列表:冒号的灵活用法介绍(np数组,列表倒序)
2018/04/18 Python
在Python中输入一个以空格为间隔的数组方法
2018/11/13 Python
Python的UTC时间转换讲解
2019/02/26 Python
PyCharm 配置远程python解释器和在本地修改服务器代码
2019/07/23 Python
Python namedtuple命名元组实现过程解析
2020/01/08 Python
Windows系统下pycharm中的pip换源
2020/02/23 Python
Python 字符串池化的前提
2020/07/03 Python
使用Python爬取小姐姐图片(beautifulsoup法)
2021/02/11 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
大唐电信科技股份有限公司java工程师面试经历
2016/12/09 面试题
字符串str除首尾字符外的其他字符按升序排列
2013/03/08 面试题
水产养殖学应届生求职信
2013/09/29 职场文书
写自荐信有哪些不宜?
2013/10/17 职场文书
思想品德自我评价
2014/02/04 职场文书
订货会邀请函
2015/01/31 职场文书
英语辞职信怎么写
2015/02/28 职场文书
搞笑结婚保证书
2015/05/08 职场文书
怎样做好公众演讲能力?
2019/08/28 职场文书
关于Python中*args和**kwargs的深入理解
2021/08/07 Python