在上一篇《Angularjs開發一些經驗總結》中提到angular開發中的IOC inject優先,所以在這節將引用angularjs的注入代碼來分析angularjs的注入方式。在《再談angularjs DI(Dependency Injection)》中提到angularjs的注入方式分為3中方式,如果你還不清楚的請移步。
在這裡我們先上今天的主角code:
/**
* @ngdoc overview
* @name AUTO
* @description
*
* Implicit module which gets automatically added to each {@link AUTO.$injector $injector}.
*/
var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(.+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function annotate(fn) {
var $inject,
fnText,
argDecl,
last;
if (typeof fn == 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
arg.replace(FN_ARG, function(all, underscore, name){
$inject.push(name);
});
});
fn.$inject = $inject;
}
} else if (isArray(fn)) {
last = fn.length - 1;
assertArgFn(fn[last], 'fn')
$inject = fn.slice(0, last);
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}
在上面code中我們可夠很清晰的看到首先這裡會判斷是不是一個'function',如果是的我們這會判斷fn.$inject為空白,不為空白則返回此注入(標記注入),為空白則會根據正則匹配擷取參數列表,注入服務的名字按名注入;相反如果不是'function'而是Array的話擷取前n-1的服務名稱注入,這是內聯注入。
關於angularjs注入就到這裡,在最後想說下說這代碼中我們能擷取的兩個javascript技巧:
arg.replace(FN_ARG, function(all, underscore, name){
$inject.push(name);
});
關於這點可以參考《JavaScript 函數replace揭秘》。
本文出自 “破狼” 部落格,請務必保留此出處http://whitewolfblog.blog.51cto.com/3973901/1163249