[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*([^\)]*)\)/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反射依赖注入新的理解,记录之,谨防忘记.

时间: 2024-11-08 18:52:03

[javascript] 反射与依赖注入!的相关文章

[译]javascript中的依赖注入

前言 在上文介绍过控制反转之后,本来打算写篇文章介绍下控制反转的常见模式-依赖注入.在翻看资料的时候,发现了一篇好文Dependency injection in JavaScript,就不自己折腾了,结合自己理解翻译一下,好文共赏. 我喜欢引用这样一句话'编程是对复杂性的管理'.可能你也听过计算机世界是一个巨大的抽象结构.我们简单的包装东西并重复的生产新的工具.思考那么一下下,我们使用的编程语言都包括内置的功能,这些功能可能是基于其他低级操作的抽象方法,包括我们是用的javascript. 迟

laravel中如何利用反射实现依赖注入

依赖注入 在一个类中经常会依赖于其他的对象,先看一下经典的写法 class Foo { public $bar; public function __construct() { $this->bar = new Bar(); } } $foo = new Foo(); 当类的依赖发生改变时,比如 Bar 这个类需要实例化参数时,而依赖于它的类有很多,总不能一个一个地去修改吧. 再看一下使用 依赖注入 怎么做 class Foo { public $bar; public function __c

Java反射及依赖注入简单模拟

一.编写Dao类 ? 1 2 3 4 5 6 7 8 9 10 11 package cn.com.songjy.annotation; import java.util.Date; public class MyDao {     public String time(){         return "你好,现在的时间是:" + new Date();     }      } 二.编写属性文件[my.properties,类似spring的配置文件]并将MyDao类配置到其中,

浅谈依赖注入与控制反转

前言:设计模式其实是一个很空洞的东西,设计模式有几十种,有些人觉得工厂模式也单例模式已经足够解决大部分问题.而有些人觉得任何设计模式都会让开发变得更“复杂”,更“低效”.所以千万不要太过追求他的实际意义和作用,否则你已经坠入云雾.但是不管怎么样,实际工作中还是要对它们有所了解,下面从php的角度来讲一下依赖注入.控制反转.反射等概念.如有错误之处,还望路过大神多加指点 首先设定场景,假如一个类需要数据库连接,最简单的做法可能是: class example { private $_db; fun

讲解依赖注入的好文-目前唯一

以前对于依赖注入概念很模糊,甚至已经用到了但是我却不知道它就是依赖注入.直到看到这篇文章. 如果看了之后还是很模糊,可以进入页终链接,找到博主上一篇文章的有趣小例子. 2.2 正式定义依赖注入 下面,用稍微正式一点的语言,定义依赖注入产生的背景缘由和依赖注入的含义.在读的过程中,读者可以结合上面的例子进行理解. 依赖注入产生的背景: 随着面向对象分析与设计的发展,一个良好的设计,核心原则之一就是将变化隔离,使得变化部分发生变化时,不变部分不受影响(这也是OCP的目的).为了做到这一点,要利用面向

依赖注入那些事儿

from:http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html 目录 目录 1 IGame游戏公司的故事 1.1 讨论会 1.2 实习生小李的实现方法 1.3 架构师的建议 1.4 小李的小结 2 探究依赖注入 2.1 故事的启迪 2.2 正式定义依赖注入 3 依赖注入那些事儿 3.1 依赖注入的类别 3.1.1 Setter注入 3.1.2 Construtor注入 3.1.3 依赖获取 3.2 反射与依赖注入 3.3 多

C# 依赖注入

http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html 这篇文章真的非常非常好···绝对值得收藏学习. 目录 目录 1 IGame游戏公司的故事 1.1 讨论会 1.2 实习生小李的实现方法 1.3 架构师的建议 1.4 小李的小结 2 探究依赖注入 2.1 故事的启迪 2.2 正式定义依赖注入 3 依赖注入那些事儿 3.1 依赖注入的类别 3.1.1 Setter注入 3.1.2 Construtor注入 3.1.3 依赖获

Android开发中依赖注入的应用

什么是依赖注入? 依赖是指一个对象持有其他对象的引用.依赖注入则是将这些依赖对象传递给被依赖对象,而不是被依赖对象自己创建这些对象. public class MyClass{ private AnotherClass mAnotherObject; public MyClass(){ mAnotherObject = new AnotherClass(); } } 通过传递对象的方式,所传递对象的更改不会影响代码. public class MyClass{ private MyInterfa

【转】依赖注入那些事儿

[转]依赖注入那些事儿 目录 目录 1 IGame游戏公司的故事 1.1 讨论会 1.2 实习生小李的实现方法 1.3 架构师的建议 1.4 小李的小结 2 探究依赖注入 2.1 故事的启迪 2.2 正式定义依赖注入 3 依赖注入那些事儿 3.1 依赖注入的类别 3.1.1 Setter注入 3.1.2 Construtor注入 3.1.3 依赖获取 3.2 反射与依赖注入 3.3 多态的活性与依赖注入 3.3.1 多态性的活性 3.3.2 不同活性多态性依赖注入的选择 4 IoC Contai