先看一些辅助函数 utils.js文件

文件中主要就是一个判断函数,比如isNumber isArray isString isBuffer等.判断方式是用Object.prototype.string.call()方法

也有几个其他的函数, 第一个是forEach. 此方法并非数组的forEach方法,而是将对象或者数组的值或者元素传给回调函数, 此方法在很多地方都被使用

/**
 * 迭代一个数组或者对象,为每个元素都触发一个函数.
 *
 * 如果obj是一个数组, 回调函数会被调用,参数是数组的
 * 每一个元素,下标和整个数组
 *
 * 如果obj是一个对象,回调函数会被调用,参数是对象的
 * 值,键和整个对象
 *
 * @param {Object|Array} obj 可 iterate的对象
 * @param {Function} fn 回调函数
 */
function forEach(obj, fn) {
  // 什么都没有
  if (obj === null || typeof obj === 'undefined') {
    return;
  }

  // 如果不是数组,强制变成数组
  if (typeof obj !== 'object') {
    /*eslint no-param-reassign:0*/
    obj = [obj];
  }

  if (isArray(obj)) {
    // 迭代数组的值
    for (var i = 0, l = obj.length; i < l; i++) {
      fn.call(null, obj[i], i, obj);
    }
  } else {
    // 迭代数组的键
    for (var key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        fn.call(null, obj[key], key, obj);
      }
    }
  }
}

第二个是merge,就是将多个对象合并为一个对象,不仅可以同级合并,还能合并到子级

/**
 * 接收可变参数,希望每个参数都是个对象, 
 * 然后合并每个对象的属性并返回结果.
 *
 * 当有几个对象拥有相同的属性时,后者会覆盖前者
 *
 * 例如:
 *
 * ```js
 * var result = merge({foo: 123}, {foo: 456});
 * console.log(result.foo); // outputs 456
 * ```
 *
 * @param {Object} obj1 要合并的对象
 * @returns {Object} 合并属性以后的结果
 */
function merge(/* obj1, obj2, obj3, ... */) {
  var result = {};
  function assignValue(val, key) {
    if (isPlainObject(result[key]) && isPlainObject(val)) {
      result[key] = merge(result[key], val);
    } else if (isPlainObject(val)) {
      result[key] = merge({}, val);
    } else if (isArray(val)) {
      result[key] = val.slice();
    } else {
      result[key] = val;
    }
  }

  for (var i = 0, l = arguments.length; i < l; i++) {
    forEach(arguments[i], assignValue);
  }
  return result;
}

第三个是extend函数,顾名思义就是继承(并非原型链继承或者类的继承, 而是对象的继承)

/**
 * 对象b的属性添加到对象a上.
 *
 * @param {Object} a 对象a
 * @param {Object} b 要复制属性的对象b
 * @param {Object} thisArg this指向
 * @return {Object} 对象a的结果值
 */
function extend(a, b, thisArg) {
  forEach(b, function assignValue(val, key) {  // forEach就是上面的forEach方法
    if (thisArg && typeof val === 'function') {
      a[key] = bind(val, thisArg); // 调用a[key]这个方法是,参数会传给val  相当于是val.apply(thisArg, args)
    } else {
      a[key] = val;
    }
  });
  return a;
}
// bind方法
function bind(fn, thisArg) {
  return function wrap() {
    var args = new Array(arguments.length);
    for (var i = 0; i < args.length; i++) {
      args[i] = arguments[i];
    }
    return fn.apply(thisArg, args);  // fn的作用域中可以拿到thisArg中的属性和方法
  };
};

杨柳岸残月孤轮
44 声望1 粉丝

« 上一篇
极光字体
下一篇 »
axios源码(四)