JavaScript反射與依賴注入實例詳解
本文實例講述了JavaScript反射與依賴注入。分享給大家供大家參考,具體如下:
對于javascript中的反射的理解,一直都是認(rèn)為,利用數(shù)組對回調(diào)函數(shù)進(jìn)行保存,之后在適當(dāng)?shù)臅r刻利用call或是apply 方法,對回調(diào)進(jìn)行調(diào)用即可,一般如下操作:
首先定義兩個方法:
var service = function() { return { name: 'Service' }; } var router = function() { return { name: 'Router' }; }
我們有另一個函數(shù)需要用到這兩個模塊。
var doSomething = function(other) { var s = service(); var r = router(); };
當(dāng)然,我們希望能夠能夠使用依賴注入的方式去做,把該控制權(quán)交給計算機(jī)去做,而不是人為的去調(diào)用如下:
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 用來保存回調(diào)函數(shù)集合,resolve用來調(diào)用。
這也算是一個比較成熟ok的想法。
但是依舊存在幾點問題:
1 resolve 在進(jìn)行調(diào)用時,deps參數(shù)列表順序必須保持一致。
2 這一點有點牽強(qiáng),但是也算。在調(diào)用時,需要再一次的輸入形參,而不能直接調(diào)用。
那么為了解決以上問題,給出以下解決方案:
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); } } };
利用正則對代碼進(jìn)行解析,解析出function 列表參數(shù),再進(jìn)行一一自動匹配傳值,那么即可解決,順序必須一直問題,當(dāng)然這也是當(dāng)然最熱mvvm框架AngularJs采取的方式。
調(diào)用方式可以如下:
injector.resolve(['service,,router', function(service, router) { }]);
你可能注意到在第一個參數(shù)后面有兩個逗號——注意
這不是筆誤。空值實際上代表“Other”參數(shù)(占位符)。這顯示了我們是如何控制參數(shù)順序的。
最后還有一種方式,直接注入scope ,也就是直接注入作用域,那么作用域被注入,也就不存在上述的傳參順序問題
因為不在需要傳遞參數(shù),直接可以從作用域中訪問到。
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反射依賴注入新的理解,記錄之,謹(jǐn)防忘記.
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
相關(guān)文章
使用JavaScript實現(xiàn)頁面局部更新的方法總結(jié)
在JavaScript中,Ajax(Asynchronous JavaScript and XML)是一種用于在后臺與服務(wù)器進(jìn)行異步通信的技術(shù),本文給大家介紹了使用JavaScript實現(xiàn)頁面局部更新的三種方法,文中通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12改變checkbox默認(rèn)選中狀態(tài)及取值的實現(xiàn)代碼
下面小編就為大家?guī)硪黄淖僣heckbox默認(rèn)選中狀態(tài)及取值的實現(xiàn)代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05學(xué)習(xí)javascript,實現(xiàn)插入排序?qū)崿F(xiàn)代碼
首先新建一個空列表,用于保存已排序的有序數(shù)列(我們稱之為"有序列表")。從原數(shù)列中取出一個數(shù),將其插入"有序列表"中,使其仍舊保持有序狀態(tài)。2011-07-07JS開發(fā)中百度地圖+城市聯(lián)動實現(xiàn)實時觸發(fā)查詢地址功能
這篇文章主要介紹了JS開發(fā)中百度地圖+城市聯(lián)動實現(xiàn)實時觸發(fā)查詢地址功能,需要的朋友可以參考下2017-04-04關(guān)于ligerui子頁面關(guān)閉后,父頁面刷新,重新加載的方法
今天小編就為大家分享一篇關(guān)于ligerui子頁面關(guān)閉后,父頁面刷新,重新加載的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09JavaScript瀑布流的實現(xiàn)你學(xué)會了嗎
這篇文章主要為大家詳細(xì)介紹了JavaScript瀑布流的實現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02