中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

JavaScript中的依賴注入詳解
來源:易賢網 閱讀:3086 次 日期:2015-03-19 14:53:03
溫馨提示:易賢網小編為您整理了“JavaScript中的依賴注入詳解”,方便廣大網友查閱!

這篇文章主要介紹了JavaScript中的依賴注入詳解,本文講解了requirejs/AMD方法、反射(reflection)方法等內容,需要的朋友可以參考下

計算機編程的世界其實就是一個將簡單的部分不斷抽象,并將這些抽象組織起來的過程。JavaScript也不例外,在我們使用JavaScript編寫應用時,我們是不是都會使用到別人編寫的代碼,例如一些著名的開源庫或者框架。隨著我們項目的增長,我們需要依賴的模塊變得越來越多,這個時候,如何有效的組織這些模塊就成了一個非常重要的問題。依賴注入解決的正是如何有效組織代碼依賴模塊的問題。你可能在一些框架或者庫種聽說過“依賴注入”這個詞,比如說著名的前端框架AngularJS,依賴注入就是其中一個非常重要的特性。但是,依賴注入根本就不是什么新鮮玩意,它在其他的編程語言例如PHP中已經存在已久。同時,依賴注入也沒有想象種那樣復雜。在本文中,我們將一起來學習JavaScript中的依賴注入的概念,深入淺出的講解如何編寫“依賴注入風格”的代碼。

名單

JavaScript中的依賴注入詳解 三聯

目標設定

假設我們現在擁有兩個模塊。第一個模塊的作用是發送Ajax請求,而第二個模塊的作用則是用作路由。

代碼如下:

var service = function() {

return { name: 'Service' };

}

var router = function() {

return { name: 'Router' };

}

這時,我們編寫了一個函數,它需要使用上面提到的兩個模塊:

代碼如下:

var doSomething = function(other) {

var s = service();

var r = router();

};

在這里,為了讓我們的代碼變得有趣一些,這個參數需要多接收幾個參數。當然,我們完全可以使用上面的代碼,但是無論從哪個方面來看上面的代碼都略顯得不那么靈活。要是我們需要使用的模塊名稱變為ServiceXML或者ServiceJSON該怎么辦?或者說如果我們基于測試的目的想要去使用一些假的模塊改怎么辦。這時,我們不能僅僅去編輯函數本身。因此我們需要做的第一件事情就是將依賴的模塊作為參數傳遞給函數,代碼如下所示:

代碼如下:

var doSomething = function(service, router, other) {

var s = service();

var r = router();

};

在上面的代碼中,我們完全傳遞了我們所需要的模塊。但是這又帶來了一個新的問題。假設我們在代碼的哥哥部分都調用了doSomething方法。這時,如果我們需要第三個依賴項該怎么辦。這個時候,去編輯所有的函數調用代碼并不是一個明智的方法。因此,我們需要一段代碼來幫助我們做這件事情。這就是依賴注入器試圖去解決的問題?,F在我們可以來定下我們的目標了:

1.我們應該能夠去注冊依賴項

2.依賴注入器應該接收一個函數,然后返回一個能夠獲取所需資源的函數

3.代碼不應該復雜,而應該簡單友好

4.依賴注入器應該保持傳遞的函數作用域

5.傳遞的函數應該能夠接收自定義的參數,而不僅僅是被描述的依賴項

requirejs/AMD方法

或許你已經聽說過了大名鼎鼎的requirejs,它是一個能夠很好的解決依賴注入問題的庫:

代碼如下:

define(['service', 'router'], function(service, router) {

// ...

});

requirejs的思想是首先我們應該去描述所需要的模塊,然后編寫你自己的函數。其中,參數的順序很重要。假設我們需要編寫一個叫做injector的模塊,它能夠實現類似的語法。

代碼如下:

var doSomething = injector.resolve(['service', 'router'], function(service, router, other) {

expect(service().name).to.be('Service');

expect(router().name).to.be('Router');

expect(other).to.be('Other');

});

doSomething("Other");

在繼續往下之前,需要說明的一點是在doSomething的函數體中我們使用了expect.js這個斷言庫來確保代碼的正確性。這里有一點類似TDD(測試驅動開發)的思想。

現在我們正式開始編寫我們的injector模塊。首先它應該是一個單體,以便它能夠在我們應用的各個部分都擁有同樣的功能。

代碼如下:

var injector = {

dependencies: {},

register: function(key, value) {

this.dependencies[key] = value;

},

resolve: function(deps, func, scope) {

}

}

這個對象非常的簡單,其中只包含兩個函數以及一個用于存儲目的的變量。我們需要做的事情是檢查deps數組,然后在dependencies變量種尋找答案。剩余的部分,則是使用.apply方法去調用我們傳遞的func變量:

代碼如下:

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)));

}

}

如果你需要指定一個作用域,上面的代碼也能夠正常的運行。

在上面的代碼中,Array.prototype.slice.call(arguments, 0)的作用是將arguments變量轉換為一個真正的數組。到目前為止,我們的代碼可以完美的通過測試。但是這里的問題是我們必須要將需要的模塊寫兩次,而且不能夠隨意排列順序。額外的參數總是排在所有的依賴項之后。

反射(reflection)方法

根據維基百科中的解釋,反射(reflection)指的是程序可以在運行過程中,一個對象可以修改自己的結構和行為。在JavaScript中,簡單來說就是閱讀一個對象的源碼并且分析源碼的能力。還是回到我們的doSomething方法,如果你調用doSomething.toString()方法,你可以獲得下面的字符串:

代碼如下:

"function (service, router, other) {

var s = service();

var r = router();

}"

這樣一來,只要使用這個方法,我們就可以輕松的獲取到我們想要的參數,以及更重要的一點就是他們的名字。這也是AngularJS實現依賴注入所使用的方法。在AngularJS的代碼中,我們可以看到下面的正則表達式:

代碼如下:

/^function\s*[^\(]*\(\s*([^\)]*)\)/m

我們可以將resolve方法修改成如下所示的代碼:

代碼如下:

resolve: function() {

var func, deps, scope, args = [], self = this;

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 (service, router, other)", "service, router, other"]

此時,我們只需要第二項。但是一旦我們去除了多余的空格并以,來切分字符串以后,我們就得到了deps數組。下面的代碼就是我們進行修改的部分:

代碼如下:

var a = Array.prototype.slice.call(arguments, 0);

...

args.push(self.dependencies[d] && d != '' ? self.dependencies[d] : a.shift());

在上面的代碼中,我們遍歷了依賴項目,如果其中有缺失的項目,如果依賴項目中有缺失的部分,我們就從arguments對象中獲取。如果一個數組是空數組,那么使用shift方法將只會返回undefined,而不會拋出一個錯誤。到目前為止,新版本的injector看起來如下所示:

代碼如下:

var doSomething = injector.resolve(function(service, other, router) {

expect(service().name).to.be('Service');

expect(router().name).to.be('Router');

expect(other).to.be('Other');

});

doSomething("Other");

在上面的代碼中,我們可以隨意混淆依賴項的順序。

但是,沒有什么是完美的。反射方法的依賴注入存在一個非常嚴重的問題。當代碼簡化時,會發生錯誤。這是因為在代碼簡化的過程中,參數的名稱發生了變化,這將導致依賴項無法解析。例如:

代碼如下:

var doSomething=function(e,t,n){var r=e();var i=t()}

因此我們需要下面的解決方案,就像AngularJS中那樣:

代碼如下:

var doSomething = injector.resolve(['service', 'router', function(service, router) {

}]);

這和最一開始看到的AMD的解決方案很類似,于是我們可以將上面兩種方法整合起來,最終代碼如下所示:

代碼如下:

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);

}

}

}

這一個版本的resolve方法可以接受兩個或者三個參數。下面是一段測試代碼:

代碼如下:

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");

你可能注意到了兩個逗號之間什么都沒有,這并不是錯誤。這個空缺是留給Other這個參數的。這就是我們控制參數順序的方法。

結語

在上面的內容中,我們介紹了幾種JavaScript中依賴注入的方法,希望本文能夠幫助你開始使用依賴注入這個技巧,并且寫出依賴注入風格的代碼。

更多信息請查看IT技術專欄

更多信息請查看腳本欄目
易賢網手機網站地址:JavaScript中的依賴注入詳解
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點

版權所有:易賢網

中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
日韩精品资源二区在线| 91女厕偷拍女厕偷拍高清| 亚洲人妖av一区二区| 亚洲精品在线免费观看视频| 日韩欧美的一区| 精品久久久久久久久久久院品网 | 亚洲精品乱码久久久久久黑人| 国产日韩欧美精品在线| 国产午夜精品一区二区三区嫩草| 久久五月婷婷丁香社区| 国产亚洲精品免费| 自拍偷自拍亚洲精品播放| 亚洲日本在线a| 亚洲电影一级黄| 日韩激情一二三区| 狠狠久久亚洲欧美| 成人少妇影院yyyy| 色综合久久精品| 在线91免费看| 国产精品天干天干在线综合| 国产欧美一区二区精品仙草咪 | 成人小视频免费观看| 成人黄色一级视频| 欧美丝袜丝交足nylons| 欧美一级精品大片| 国产精品久久久一区麻豆最新章节| 国产精品家庭影院| 调教+趴+乳夹+国产+精品| 久久国产精品99精品国产| 成人免费视频视频在线观看免费 | 亚洲成a人在线观看| 老司机精品视频导航| a美女胸又www黄视频久久| 欧美丰满一区二区免费视频| 久久久久久亚洲综合影院红桃| 日韩理论片一区二区| 日韩精品一区第一页| 丁香婷婷综合激情五月色| 欧美日韩一区三区四区| 国产日韩欧美高清| 日本中文字幕不卡| 91色在线porny| 久久综合五月天婷婷伊人| 亚洲另类在线视频| 不卡的av在线| 精品奇米国产一区二区三区| 亚洲色图清纯唯美| 国产精品99久久久久久久vr| 欧美日韩中文精品| 亚洲视频你懂的| 黄色日韩三级电影| 欧美精品亚洲二区| 亚洲麻豆国产自偷在线| 国产精品一线二线三线精华| 欧美久久久久中文字幕| 亚洲欧美日韩在线不卡| 国产精品中文字幕一区二区三区| 欧美日韩免费高清一区色橹橹 | 久久精品国产亚洲高清剧情介绍 | 奇米色一区二区| 色视频一区二区| 国产精品麻豆欧美日韩ww| 极品瑜伽女神91| 欧美一级日韩免费不卡| 亚洲制服欧美中文字幕中文字幕| 成人在线视频一区| 久久日一线二线三线suv| 免费人成在线不卡| 6080亚洲精品一区二区| 夜夜嗨av一区二区三区网页| 97精品电影院| 亚洲黄色性网站| 91女厕偷拍女厕偷拍高清| 国产精品久久久久婷婷| 国产a视频精品免费观看| 欧美哺乳videos| 国产在线国偷精品免费看| 日韩视频永久免费| 男女性色大片免费观看一区二区| 91精品国产色综合久久ai换脸| 婷婷久久综合九色国产成人| 欧美性生交片4| 亚洲va在线va天堂| 日韩一区二区三区免费观看| 日本午夜一本久久久综合| 91精品婷婷国产综合久久性色 | 国产欧美一区二区三区在线老狼| 国产乱码精品一区二区三区忘忧草| 精品美女在线观看| 国产福利精品一区| 亚洲欧美日本韩国| 精品视频999| 精品一区二区三区免费播放| 久久久www免费人成精品| 99久久精品国产一区二区三区| 亚洲精品成人悠悠色影视| 91黄色激情网站| 麻豆精品一区二区av白丝在线| 久久亚洲私人国产精品va媚药| 成人国产精品视频| 亚洲午夜视频在线观看| 日韩欧美在线网站| www.一区二区| 青青国产91久久久久久| 中文字幕免费一区| 欧美亚洲免费在线一区| 久久99精品国产91久久来源 | 色婷婷综合久久久久中文一区二区 | 一本一道波多野结衣一区二区| 亚洲大片在线观看| www激情久久| 91视频观看视频| 另类人妖一区二区av| 中文字幕一区二区三区色视频 | 最新热久久免费视频| 欧美日韩综合不卡| 国产精品一区二区无线| 亚洲一区二区在线播放相泽| 精品第一国产综合精品aⅴ| 99精品在线免费| 国内精品视频666| 午夜视频在线观看一区| 中日韩av电影| 精品美女在线观看| 欧美日韩一区不卡| 99久久婷婷国产| 韩国一区二区三区| 香蕉久久一区二区不卡无毒影院 | 成人性生交大片免费看中文| 性感美女久久精品| 一区二区三区蜜桃网| 久久久久成人黄色影片| 欧美一区三区四区| 欧洲一区二区三区在线| jizz一区二区| 精品一区二区三区欧美| 日本免费在线视频不卡一不卡二| 亚洲婷婷在线视频| 国产精品看片你懂得 | heyzo一本久久综合| 国产成人免费av在线| 久久精品国产亚洲5555| 日日骚欧美日韩| 午夜精品久久久久久久久| 亚洲黄色性网站| 亚洲精品欧美激情| 一级女性全黄久久生活片免费| 亚洲女同ⅹxx女同tv| 亚洲丝袜美腿综合| 国产精品久久久久9999吃药| 国产欧美一区二区三区沐欲 | 91片黄在线观看| av网站一区二区三区| 99视频一区二区三区| av不卡一区二区三区| 成人国产亚洲欧美成人综合网| 成人av中文字幕| av综合在线播放| 91看片淫黄大片一级在线观看| 91免费在线播放| 91福利视频网站| 欧美日韩一二区| 日韩欧美二区三区| 久久精品一区二区三区不卡| 国产偷国产偷精品高清尤物| 中文字幕不卡三区| 亚洲视频你懂的| 天天色 色综合| 理论片日本一区| 成人免费看黄yyy456| 91蜜桃免费观看视频| 欧美日韩国产一级片| 日韩欧美一区二区视频| 国产精品丝袜一区| 亚洲综合成人在线| 精品一二三四在线| 成人精品国产福利| 欧美日韩日日夜夜| 精品国产电影一区二区| 国产精品久久久久久久久搜平片| 亚洲女与黑人做爰| 韩国三级中文字幕hd久久精品| 成人avav影音| 欧美一区二区三区在线视频| 国产午夜亚洲精品羞羞网站| 亚洲自拍偷拍麻豆| 精品系列免费在线观看| 99久久国产综合色|国产精品| 欧美日韩亚洲综合一区二区三区| 久久精品男人的天堂| 亚洲国产一区二区视频| 国产综合色视频| 欧美三区在线观看| 国产精品视频看| 日本在线不卡视频| 色噜噜夜夜夜综合网| 久久久久久久久久久久久夜| 亚洲第一福利一区| www.激情成人| 美腿丝袜一区二区三区|