AngularJS-源码阅读(五)

   现在我们来接触一下AngularJS的DI($injector)。先从注入参数的解析开始:

function assertArgFn(arg, name, acceptArrayAnnotation) {
  if (acceptArrayAnnotation && isArray(arg)) {
      arg = arg[arg.length - 1];
  }

  assertArg(isFunction(arg), name, 'not a function, got ' +
      (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg));
      //用来判定是否指function,不是的话,抛出相应的异常。
  return arg;
}



var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;//用来去除 function(a,b/*注释*/,c){} 中参数注释
var $injectorMinErr = minErr('$injector');
function annotate(fn) {
  var $inject,
      fnText,
      argDecl,
      last;

  if (typeof fn == 'function') {
    if (!($inject = fn.$inject)) {
      $inject = [];
      if (fn.length) {
        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;//将要注入的部件名称数组,绑定到fn函数中。
    }
  } else if (isArray(fn)) {//判定fn是否为数组->判定数组fn最后一个是不是function->将fn数组前面的参数赋值给$inject
    last = fn.length - 1;
    assertArgFn(fn[last], 'fn');
    $inject = fn.slice(0, last);
  } else {
    assertArgFn(fn, 'fn', true);//这个地方的代码有些绕圈,作用仅为抛出相应异常。o(╯□╰)o。true 参数是用来提高性能,减少fn是否为Array的判定。
  }
  return $inject;
}

 以上代码主要是用来获取需要注入的参数。下面是例子

var a =[$a,$b,$c,function fn(...){...}];//$a,$b,$c为要注入到fn函数的具体引用。
annotate(a)   //=>[$a,$b,$c]; 
var b =function(a,b/*我是注释*/,c);
annotate(b)  //=>[a,b,c] 注意,这里a、b、c为字符串而不是引用。


 


你可能感兴趣的:(AngularJS-源码阅读(五))