AngularJS-源碼閱讀(一)

function minErr(module) {
  return function () {
    var code = arguments[0],
      prefix = '[' + (module ? module + ':' : '') + code + '] ',
      template = arguments[1],
      templateArgs = arguments,
      stringify = function (obj) {
        if (typeof obj === 'function') {
          return obj.toString().replace(/ \{[\s\S]*$/, '');
        } else if (typeof obj === 'undefined') {
          return 'undefined';
        } else if (typeof obj !== 'string') {
          return JSON.stringify(obj);
        }
        return obj;
      },
      message, i;

    message = prefix + template.replace(/\{\d+\}/g, function (match) {
      var index = +match.slice(1, -1), arg;

      if (index + 2 < templateArgs.length) {
        arg = templateArgs[index + 2];
        if (typeof arg === 'function') {
          return arg.toString().replace(/ ?\{[\s\S]*$/, '');
        } else if (typeof arg === 'undefined') {
          return 'undefined';
        } else if (typeof arg !== 'string') {
          return toJson(arg);
        }
        return arg;
      }
      return match;
    });

    message = message + '\nhttp://errors.angularjs.org/1.2.5/' +
      (module ? module + '/' : '') + code;
    for (i = 2; i < arguments.length; i++) {
      message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
        encodeURIComponent(stringify(arguments[i]));
    }

    return new Error(message);
  };
}

 這是angularJs最開始的一個函數,用來規整錯誤輸出格式的,註釋上給了個簡單的例子,可直接copy到谷歌Console上運行。本函數使用arguments調參數+返回函數的方式,增長了函數的擴展性,具體的使用方式前端

var exampleMinErr = minErr('example');
throw exampleMinErr('one', 'This {0} is {1}', "one replace", "two replace");

效果爲:node

  Error: [example:one] This one replace is two replace http://errors.angularjs.org/1.2.5/example/one?p0=one%20replace&p1=two%20replace angularjs

  

//var values = {name: 'misko', gender: 'male'};
//var log = [];
//forEach(values, function(value, key){
//  this.push(key + ': ' + value);
//}, log);

function forEach(obj, iterator, context) {
  var key;
  if (obj) {
    if (isFunction(obj)){
      for (key in obj) {
        if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
          iterator.call(context, obj[key], key);
        }
      }
    } else if (obj.forEach && obj.forEach !== forEach) {
      obj.forEach(iterator, context);
    } else if (isArrayLike(obj)) {
      for (key = 0; key < obj.length; key++)
        iterator.call(context, obj[key], key);
    } else {
      for (key in obj) {
        if (obj.hasOwnProperty(key)) {
          iterator.call(context, obj[key], key);
        }
      }
    }
  }
  return obj;
}

        對於我等碰見對象遍歷就for in,碰見數組就for(;<.length;)的屌絲來講,一個方法搞定。該方法添加了對Function的遍歷。該方法中有個須要一提的isArrayLike的函數,除了Array類型, 還有遊覽器的NodeList和String類型,後臺用到該方法時候,能夠幹掉NodeList。數組

/**
 * @private
 * @param {*} obj
 * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
 *                   String ...)
 */
function isArrayLike(obj) {
  if (obj == null || isWindow(obj)) {
    return false;
  }

  var length = obj.length;

  if (obj.nodeType === 1 && length) {
    return true;
  }

  return isString(obj) || isArray(obj) || length === 0 ||
         typeof length === 'number' && length > 0 && (length - 1) in obj;
}



//脫去前端適配後
//function isArrayLike(obj) {
//  return isString(obj) || isArray(obj);
//}
相關文章
相關標籤/搜索