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

 更新时间:2018年05月29日 14:15:37   作者:梦你所梦  
这篇文章主要介绍了JavaScript反射与依赖注入,结合实例形式较为详细的分析了JavaScript反射与依赖注入的概念、原理、定义、使用方法及相关操作注意事项,需要的朋友可以参考下

本文实例讲述了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错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结

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

相关文章

  • JavaScript 的方法重载效果

    JavaScript 的方法重载效果

    JavaScript 语言的方法声明中,不能明确指定参数的类型和个数,所以不能实现方法的重载,但是我们可以用其他的方法来实现重载的效果。
    2009-08-08
  • 解决使用attachEvent函数时,this指向被绑定的元素的问题的方法

    解决使用attachEvent函数时,this指向被绑定的元素的问题的方法

    解决使用attachEvent函数时,this指向被绑定的元素的问题的方法...
    2007-08-08
  • 网站页面自动跳转实现方法PHP、JSP(下)

    网站页面自动跳转实现方法PHP、JSP(下)

    很多时候我们需要Web页具备有自动跳转功能,例如,论坛中的用户登录、发帖及回复或留言簿中的留言和回复等操作成功后,若用户没有任何鼠标点击操作,过了一定的时间,页面自动跳转到预设的页面。
    2010-08-08
  • 用js编写简单的贪吃蛇小游戏

    用js编写简单的贪吃蛇小游戏

    这篇文章主要为大家详细介绍了用js编写简单的贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • JavaScript实现开关等效果

    JavaScript实现开关等效果

    本文给大家分享一段简单的代码基于js实现开关灯效果,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-09-09
  • CSS+Js遮罩效果的TAB及焦点图片切换(推荐)

    CSS+Js遮罩效果的TAB及焦点图片切换(推荐)

    CSS+Js图片切换技术,类似的已有不少了,这一个使用了遮罩过渡的效果,同样应用到了TAB选项卡上,本页面仅是为了演示,大家用时候把它拆分开来,这个效果也对学习图片效果制作很有帮助。
    2009-11-11
  • uniapp引入axios异步框架的完整步骤

    uniapp引入axios异步框架的完整步骤

    虽然Uniapp可以使用Vue.js自带的$http,但也可以使用Axios,只需要在项目中进行简单的配置,这篇文章主要给大家介绍了关于uniapp引入axios异步框架的相关资料,需要的朋友可以参考下
    2023-12-12
  • GoJs连线绘图模板Link使用示例详解

    GoJs连线绘图模板Link使用示例详解

    这篇文章主要为大家介绍了GoJs连线绘图模板Link使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 小程序中this.setData的使用和注意事项

    小程序中this.setData的使用和注意事项

    这篇文章主要介绍了微信小程序中this.setData的使用和注意事项,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • 前端使用websocket发送消息的示例代码

    前端使用websocket发送消息的示例代码

    WebSocket是一种在单个TCP连接上进行全双工通信的协议,它可以让客户端和服务器之间进行实时的双向通信,这篇文章主要介绍了前端使用websocket发送消息的示例代码,需要的朋友可以参考下
    2023-07-07

最新评论