先看一些辅助函数 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 中的属性和办法
};
};