繼續學習lodash,依然是數組的方法
“Array” Methods
_.take(array, [n=1])
創建一個數組片段包含從數組開始獲取的n個元素.
//take.js var baseSlice = require('./_baseSlice'),//同Array.slice(見源碼學習(3)) toInteger = require('./toInteger');//轉化為整型 /** * * @param {Array} array 需要查詢的數組. * @param {number} [n=1] 需要獲取的數量. * @param- {Object} [guard] 能夠作為遍歷器被像_.map這樣的方法調用. * @returns {Array} 返回切好的數組. * @example * * _.take([1, 2, 3]); * // => [1] * * _.take([1, 2, 3], 2); * // => [1, 2] * * _.take([1, 2, 3], 5); * // => [1, 2, 3] * * _.take([1, 2, 3], 0); * // => [] */ function take(array, n, guard) { if (!(array && array.length)) {//如果沒有array,或者為空數組,返回空數組 return []; } n = (guard || n === undefined) ? 1 : toInteger(n);//n默認為1 return baseSlice(array, 0, n < 0 ? 0 : n);//調用baseSlice方法並將結果作為返回值返回 } module.exports = take;
_.takeRight(array, [n=1])
創建一個數組片段包含從數組末尾獲取的n個元素..
//takeRight.js var baseSlice = require('./_baseSlice'),//同Array.slice toInteger = require('./toInteger');//轉化為整型 /** * * @param {Array} array 需要查詢的數組. * @param {number} [n=1] 需要獲取的元素數量. * @param- {Object} [guard] 能夠作為遍歷器被像_.map這樣的方法調用. * @returns {Array} 返回切好的數組片段. * @example * * _.takeRight([1, 2, 3]); * // => [3] * * _.takeRight([1, 2, 3], 2); * // => [2, 3] * * _.takeRight([1, 2, 3], 5); * // => [1, 2, 3] * * _.takeRight([1, 2, 3], 0); * // => [] */ function takeRight(array, n, guard) { var length = array == null ? 0 : array.length; if (!length) {//如果沒有array,或者為空數組,返回空數組 return []; } n = (guard || n === undefined) ? 1 : toInteger(n);//n默認為1 n = length - n;//從末尾開始算 return baseSlice(array, n < 0 ? 0 : n, length);//調用baseSlice方法並將結果作為返回值返回 } module.exports = takeRight;
_.takeRightWhile(array, [predicate=_.identity])
創建一個數組,包含從數組的末尾開始獲取元素,直到判斷結果為false為止的元素.判斷條件接收三個參數(value, index, array)
//takeRightWhile.js var baseIteratee = require('./_baseIteratee'),//遍歷器封裝 baseWhile = require('./_baseWhile');//從第一個不滿足predicate 條件的元素開始截取數組(見源碼學習(1)) /** * * @param {Array} array 需要查詢的數組. * @param {Function} [predicate=_.identity] 判斷條件. * @returns {Array} 返回切好的數組片段. * @example * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * * _.takeRightWhile(users, function(o) { return !o.active; }); * // => objects for ['fred', 'pebbles'] * * // The `_.matches` iteratee shorthand. * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); * // => objects for ['pebbles'] * * // The `_.matchesProperty` iteratee shorthand. * _.takeRightWhile(users, ['active', false]); * // => objects for ['fred', 'pebbles'] * * // The `_.property` iteratee shorthand. * _.takeRightWhile(users, 'active'); * // => [] */ function takeRightWhile(array, predicate) {//如果沒有array或者為空數組,返回空數組,否則調用baseWhile方法,並將判斷條件封裝,使之支持簡寫,傳入第四個參數為true,從右邊開始。 return (array && array.length) ? baseWhile(array, baseIteratee(predicate, 3), false, true) : []; } module.exports = takeRightWhile;
_.takeWhile(array, [predicate=_.identity])
創建一個數組,包含從數組的開始開始獲取元素,直到判斷結果為false為止的元素.判斷條件接收三個參數(value, index, array)
//takeWhile.js var baseIteratee = require('./_baseIteratee'),//遍歷器封裝 baseWhile = require('./_baseWhile');//從第一個不滿足predicate 條件的元素開始截取數組(見源碼學習(1)) /** * * @param {Array} array 需要查詢的數組. * @param {Function} [predicate=_.identity] 判斷條件. * @returns {Array} 返回切好的數組片段. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.takeWhile(users, function(o) { return !o.active; }); * // => objects for ['barney', 'fred'] * * // The `_.matches` iteratee shorthand. * _.takeWhile(users, { 'user': 'barney', 'active': false }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.takeWhile(users, ['active', false]); * // => objects for ['barney', 'fred'] * * // The `_.property` iteratee shorthand. * _.takeWhile(users, 'active'); * // => [] */ function takeWhile(array, predicate) {//但是,但是沒有傳入從右邊開始 return (array && array.length) ? baseWhile(array, baseIteratee(predicate, 3)) : [];// } module.exports = takeWhile;
_.uniq(array)
創建一個數組包含原數組中的唯一值.
_.uniqBy(array, [iteratee=_.identity])
和_.uniq很像,除了它接收一個遍歷器被數組中的每個元素調用。
_.uniqWith(array, [comparator])
和_.uniq很像,除了它接收一個比較方法被數組中的每個元素調用,比較方法接收兩個參數(arrVal, othVal)
這三個方法依賴於baseUniq方法,先看源碼
//_baseUniq.js var SetCache = require('./_SetCache'),//Set緩存數組 arrayIncludes = require('./_arrayIncludes'),//同Array.includes arrayIncludesWith = require('./_arrayIncludesWith'),//同Array.includes除了它接受一個比較方法 cacheHas = require('./_cacheHas'),//判斷緩存中是否含有某個元素 createSet = require('./_createSet'),//創建Set對象 setToArray = require('./_setToArray');//將Set對象轉為數組 var LARGE_ARRAY_SIZE = 200;//大數組長度(用於數組過大時優化) /** * _.uniqBy的基本實現,不支持遍歷器的簡寫. * * @private * @param {Array} array 需要處理的數組. * @param {Function} [iteratee] 遍歷器被每個元素調用. * @param {Function} [comparator] 比較器被每個元素 調用. * @returns {Array} 返回一個沒有重復值得數組. */ function baseUniq(array, iteratee, comparator) { var index = -1,//數組索引 includes = arrayIncludes,//是否包含 length = array.length,//數組長度 isCommon = true,//是否為常規比較 result = [],//返回結果 seen = result;//返回結果的引用(保存被遍歷器調用過的值) if (comparator) {//如果有比較器,不是常規比較,並且比較方法為arrayIncludesWith isCommon = false; includes = arrayIncludesWith; } else if (length >= LARGE_ARRAY_SIZE) {//如果數組過長 var set = iteratee ? null : createSet(array); if (set) {//如果沒有傳遍歷器,只用轉為Set對象,再轉為數組,並將這個數組返回 return setToArray(set); } //傳了遍歷器的情況 isCommon = false;//也不是常規比較 includes = cacheHas;//比較方法為cacheHas seen = new SetCache;//創建一個緩存數組 } else { seen = iteratee ? [] : result;//如果有遍歷器,seen為空數組,否則為result的引用 } outer: //遍歷數組 while (++index < length) { var value = array[index],//當前元素 computed = iteratee ? iteratee(value) : value;//如果有遍歷器,對當前元素調用 value = (comparator || value !== 0) ? value : 0; if (isCommon && computed === computed) {//常規情況,並且cumputed不為NaN var seenIndex = seen.length;//當前結果索引 //遍歷seen while (seenIndex--) { //如果當前結果中包含computed,跳過 if (seen[seenIndex] === computed) { continue outer; } } if (iteratee) {//如果有遍歷器,將computed添加到seen中 seen.push(computed); } result.push(value);//將value添加到結果中 } else if (!includes(seen, computed, comparator)) {//非常規比較 if (seen !== result) {//如果seen為緩存,將computed添加到緩存中 seen.push(computed); } result.push(value);//將value添加到結果中 } } return result;//返回結果數組 } module.exports = baseUniq;
對應的方法
uniq
//uniq.js var baseUniq = require('./_baseUniq');//baseUniq方法 /** * * @param {Array} array 需要處理的數組. * @returns {Array} 返回一個沒有重復值得數組. * @example * * _.uniq([2, 1, 2]); * // => [2, 1] */ function uniq(array) { return (array && array.length) ? baseUniq(array) : [];//不解釋 } module.exports = uniq;
uniqBy
//uniqBy.js var baseIteratee = require('./_baseIteratee'),//遍歷器封裝 baseUniq = require('./_baseUniq');//baseUniq方法 /** * * * @param {Array} array 需要處理的數組. * @param {Function} [iteratee=_.identity] 遍歷器,被每個元素調用. * @returns {Array} 返回一個沒有重復值得數組. * @example * * _.uniqBy([2.1, 1.2, 2.3], Math.floor); * // => [2.1, 1.2] * * // The `_.property` iteratee shorthand. * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ function uniqBy(array, iteratee) { return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : [];//不解釋 } module.exports = uniqBy;
uniqWith
//uniqWith.js var baseUniq = require('./_baseUniq');//baseUniq方法 /** * * * @param {Array} array 需要處理的數組. * @param {Function} [comparator] 比較方法,被每個元素調用. * @returns {Array} 返回一個沒有重復值得數組. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.uniqWith(objects, _.isEqual); * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] */ function uniqWith(array, comparator) { comparator = typeof comparator == 'function' ? comparator : undefined;//比較器不為函數則為空 return (array && array.length) ? baseUniq(array, undefined, comparator) : [];//不解釋 } module.exports = uniqWith;
_.union([arrays])
創建一個數組,包含給出的所有數組的值的唯一值.
//union.js var baseFlatten = require('./_baseFlatten'),//數組扁平化(見源碼學習(1)) baseRest = require('./_baseRest'),//創建具備rest參數的方法 baseUniq = require('./_baseUniq'),//baseUniq方法 isArrayLikeObject = require('./isArrayLikeObject');//是否是類似數組的對象 /** * * @param {...Array} [arrays] 需要處理的數組. * @returns {Array} 返回一個沒有重復值得數組. * @example * * _.union([2], [1, 2]); * // => [2, 1] */ var union = baseRest(function(arrays) { //先將給出的數組扁平化一級之后再調用baseUniq方法,並將結果作為返回值返回。 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); }); module.exports = union;
_.unionBy([arrays], [iteratee=_.identity])
這個方法和_.union很像,除了它接收一個遍歷器,被數組中的每個元素調用,遍歷器接收一個參數(value)
//unionBy.js var baseFlatten = require('./_baseFlatten'),//數組扁平化(見源碼學習(1)) baseIteratee = require('./_baseIteratee'),//遍歷器封裝 baseRest = require('./_baseRest'),//創建具備rest參數的方法 baseUniq = require('./_baseUniq'),//baseUniq方法 isArrayLikeObject = require('./isArrayLikeObject'),//是否是類似數組的對象 last = require('./last');//取得最后一個元素 /** * * @param {...Array} [arrays] 需要處理的數組. * @param {Function} [iteratee=_.identity] 遍歷器,對每個元素調用. * @returns {Array} 返回一個沒有重復值得數組. * @example * * _.unionBy([2.1], [1.2, 2.3], Math.floor); * // => [2.1, 1.2] * * // The `_.property` iteratee shorthand. * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ var unionBy = baseRest(function(arrays) {//創建可以使用rest參數的方法 var iteratee = last(arrays);//遍歷器為參數的最后一個 if (isArrayLikeObject(iteratee)) {//如果是一個數組(就是沒傳),遍歷器為undefined iteratee = undefined; } //先將給出的數組扁平化一級之后,並且將遍歷器封裝,再調用baseUniq方法,並將結果作為返回值返回。 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), baseIteratee(iteratee, 2)); }); module.exports = unionBy;
_.unionWith([arrays], [comparator])
這個方法和_.union很像,除了它接收一個比較方法,被數組中的每個元素調用,比較方法接收兩個參數(arrVal, othVal).
//uniqWith.js var baseFlatten = require('./_baseFlatten'),//數組扁平化(見源碼學習(1)) baseRest = require('./_baseRest'),//創建具備rest參數的方法 baseUniq = require('./_baseUniq'),//baseUniq方法 isArrayLikeObject = require('./isArrayLikeObject'),//是否是類似數組的對象 last = require('./last');//取得最后一個元素 /** * * * @param {...Array} [arrays] 需要處理的數組. * @param {Function} [comparator] 比較方法被每個元素調用. * @returns {Array} 返回一個沒有重復值得數組. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.unionWith(objects, others, _.isEqual); * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] */ var unionWith = baseRest(function(arrays) {//創建可以使用rest參數的方法 var comparator = last(arrays);//比較方法為最后一個參數 comparator = typeof comparator == 'function' ? comparator : undefined;//如果不是函數,比較方法為undefined //調用baseUniq方法,並將結果作為返回值返回。 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); }); module.exports = unionWith;
_.unzip(array)
_.zip的逆向,接收一個數組包含組合好的元素,然后創建一個數組重新分組這些元素到展開的狀態
//unzip.js var arrayFilter = require('./_arrayFilter'),//同Array.filter arrayMap = require('./_arrayMap'),//同Array.map baseProperty = require('./_baseProperty'),//通過key獲取對象的value baseTimes = require('./_baseTimes'),//調用方法n次,返回包含每次結果的數組 isArrayLikeObject = require('./isArrayLikeObject');//是否是一個類似數組的對象 var nativeMax = Math.max;//原生最小值方法 /** * * * @param {Array} array 收起之后的數組. * @returns {Array} 返回展開之后的數組. * @example * * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); * // => [['a', 1, true], ['b', 2, false]] * * _.unzip(zipped); * // => [['a', 'b'], [1, 2], [true, false]] */ function unzip(array) { if (!(array && array.length)) {//如果沒有穿array,或者為空數組,返回空數組 return []; } var length = 0; array = arrayFilter(array, function(group) {//返回array中,所有是數組的元素,並且取得length為最大的數組的長度 if (isArrayLikeObject(group)) { length = nativeMax(group.length, length); return true; } }); return baseTimes(length, function(index) {//調用length次方法,每次再調用map獲得array中每個元素對應index位置的值得數組,然后將包含這些這些數組的數組返回。 return arrayMap(array, baseProperty(index)); }); } module.exports = unzip;
_.unzipWith(array, [iteratee=_.identity])
這個方法和_.unzip很像,除了它接收一個遍歷器決定怎么結合這些重組的元素,遍歷器接收一個rest參數,表示每個分組中對應元素(...group)
//unzipWith.js var apply = require('./_apply'),//同Function.apply arrayMap = require('./_arrayMap'),//同Array.map unzip = require('./unzip');//unzip方法 /** * * * @param {Array} array 收起之后的數組. * @param {Function} [iteratee=_.identity] 遍歷器,決定怎么結合這些元素 * @returns {Array} 返回展開之后的數組. * @example * * var zipped = _.zip([1, 2], [10, 20], [100, 200]); * // => [[1, 10, 100], [2, 20, 200]] * * _.unzipWith(zipped, _.add); * // => [3, 30, 300] */ function unzipWith(array, iteratee) { if (!(array && array.length)) {//如果沒有array或者為空數組,返回空數組 return []; } var result = unzip(array);//調用unzip方法執行反壓縮 if (iteratee == null) {//如果沒有傳入便利器返回result return result; } return arrayMap(result, function(group) {//對結果進行遍歷,每次調用iteratee傳入每個group的所有元素,然后將處理后的結果作為每個分組的元素。 return apply(iteratee, undefined, group); }); } module.exports = unzipWith;
_.without(array, [values])
創建一個數組排除所有給定的值
//widthout.js var baseDifference = require('./_baseDifference'),//取得數組中不包含過濾數組的元素(見源碼學習(1)) baseRest = require('./_baseRest'),//創建具備rest參數的數組 isArrayLikeObject = require('./isArrayLikeObject');//是否是類似數組的對象 /** * * * @param {Array} array 需要處理的數組. * @param {...*} [values] 需要排除的值. * @returns {Array} 返回過濾后的數組. * @example * * _.without([2, 1, 2, 3], 1, 2); * // => [3] */ var without = baseRest(function(array, values) {//創建具備rest參數的數組 //如果是類似數組,調用baseDifference並將結果作為返回值返回,否則返回空數組 return isArrayLikeObject(array) ? baseDifference(array, values) : []; }); module.exports = without;
_.xor([arrays])
創建一個唯一值得數組,包含給定所有數組中symmetric difference的集合(對差等分,{1,2,3}△{2,3,4} => {1,4})
_.xorBy([arrays], [iteratee=_.identity])
這個方法和_.xor很像,除了它接收一個遍歷器對每個元素調用,生成比較標准,遍歷器接收一個參數(value)
_.xorWith([arrays], [comparator])
這個方法和_.xor很像,除了它接收一個比較器對每個元素調用,生成比較標准,比較器接收兩個參數(arrVal,othVal)
這三個方法依賴於baseXor方法,先看源碼
//_baseXor.js var baseDifference = require('./_baseDifference'),//取得數組中不包含過濾數組的元素(見源碼學習(1)) baseFlatten = require('./_baseFlatten'),//數組扁平化(見源碼學習(1)) baseUniq = require('./_baseUniq');//得到數組中唯一值 /** * _.xor的基本實現,不支持遍歷器的簡寫 * * @private * @param {Array} arrays 需要處理的數組. * @param {Function} [iteratee] 遍歷器被每個元素調用. * @param {Function} [comparator] 比較器被每個元素調用. * @returns {Array} 返回一個新的數組. */ function baseXor(arrays, iteratee, comparator) { var length = arrays.length;//數組長度 if (length < 2) {//如果數組中元素個數小於2 return length ? baseUniq(arrays[0]) : [];//如果有值得到第一個值得唯一值,否則空數組 } var index = -1,//數組索引 result = Array(length);//返回結果 //遍歷arrays while (++index < length) { var array = arrays[index],//當前數組 othIndex = -1;//用於比較的數組的索引 //遍歷用於比較的數組 while (++othIndex < length) { if (othIndex != index) {//如果比較的數組和當前數組不是同一個數組,調用baseDifference方法取得array中不同於當前用於比較的數組的值 result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); } } } //調用baseUiq方法,並且將result扁平化一級,然后將得到的唯一值數組返回 return baseUniq(baseFlatten(result, 1), iteratee, comparator); } module.exports = baseXor;
對應的方法
xor
//xor.js var arrayFilter = require('./_arrayFilter'),//同Array.filter baseRest = require('./_baseRest'),//創建具有rest參數的方法 baseXor = require('./_baseXor'),//baseXor方法 isArrayLikeObject = require('./isArrayLikeObject');//是否是類似數組的對象 /** * * * @param {...Array} [arrays] 需要處理的數組. * @returns {Array} 返回過濾后的數組. * @example * * _.xor([2, 1], [2, 3]); * // => [1, 3] */ var xor = baseRest(function(arrays) {//創建具有rest參數的方法 return baseXor(arrayFilter(arrays, isArrayLikeObject));//調用baseXor並將結果作為返回值返回 }); module.exports = xor;
xorBy
//xorBy.js var arrayFilter = require('./_arrayFilter'),//同Array.filter baseIteratee = require('./_baseIteratee'),//遍歷器封裝 baseRest = require('./_baseRest'),//創建具備rest參數的方法 baseXor = require('./_baseXor'),//baseXor方法 isArrayLikeObject = require('./isArrayLikeObject'),//是否是一個類似數組的對象 last = require('./last');//取得數組最后一個元素 /** * * * @param {...Array} [arrays] 需要處理的數組. * @param {Function} [iteratee=_.identity] 遍歷器被每個元素調用. * @returns {Array} 返回過濾后的數組. * @example * * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [1.2, 3.4] * * // The `_.property` iteratee shorthand. * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 2 }] */ var xorBy = baseRest(function(arrays) {//轉化arrays為rest參數 var iteratee = last(arrays);//遍歷器為最后一個參數 if (isArrayLikeObject(iteratee)) {//最后一個參數為數組,遍歷器為undefined iteratee = undefined; } //調用baseXor並且封裝遍歷器,然后將結果作為返回值返回 return baseXor(arrayFilter(arrays, isArrayLikeObject), baseIteratee(iteratee, 2)); }); module.exports = xorBy;
xorWith
//xorWith.js var arrayFilter = require('./_arrayFilter'),//同Array.filter baseRest = require('./_baseRest'),//創建具備rest參數的方法 baseXor = require('./_baseXor'),//baseXor方法 isArrayLikeObject = require('./isArrayLikeObject'),//是否是一個類似數組的對象 last = require('./last');//取得數組最后一個元素 /** * * * @param {...Array} [arrays] 需要處理的數組. * @param {Function} [comparator] 比較器被每個元素調用. * @returns {Array} 返回過濾后的數組. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.xorWith(objects, others, _.isEqual); * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] */ var xorWith = baseRest(function(arrays) {//創建使用rest參數的方法 var comparator = last(arrays);//比較器為最后一個參數 comparator = typeof comparator == 'function' ? comparator : undefined;//比較器不是函數則為undefined //調用baseXor並且傳入比較器,然后將結果作為返回值返回 return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); }); module.exports = xorWith;
_.zip([arrays])
創建一個數組包含分組之后的元素,第一個元素為所有給出的數組的第一個元素,第二個元素為所有給出的數組的第二個元素,以此類推。
//zip.js var baseRest = require('./_baseRest'),//創建具備rest參數的方法 unzip = require('./unzip');//收起方法 /** * * * @param {...Array} [arrays] 需要處理的數組. * @returns {Array} 返回收起之后的數組. * @example * * _.zip(['a', 'b'], [1, 2], [true, false]); * // => [['a', 1, true], ['b', 2, false]] */ var zip = baseRest(unzip);//創建unzip的rest參數模式 module.exports = zip;
_.zipObject([props=[]], [values=[]])
接收兩個數組轉化為對象,將第一個數組作為對象的屬性,第二個作為對象的值,返回這個對象
這個方法依賴於baseZipObject和assignValue方法,assignValue方法依賴於baseAssignValue方法
baseZipObject
//_baseZipObject.js /** * _.zipObject的基本實現,通過assignFunc進行賦值 * * @param {Array} props 屬性名. * @param {Array} values 屬性值. * @param {Function} assignFunc 賦值方法. * @returns {Object} 返回新的對象. */ function baseZipObject(props, values, assignFunc) { var index = -1,//索引值 length = props.length,//屬性名個數 valsLength = values.length,//屬性值個數 result = {};//返回結果對象 while (++index < length) {//遍歷屬性名,如果對應的屬性值沒有則為undefined var value = index < valsLength ? values[index] : undefined; assignFunc(result, props[index], value);//使用賦值函數進行賦值 } return result;//返回結果 } module.exports = baseZipObject;
baseAssignValue
//_baseAssignValue.js var defineProperty = require('./_defineProperty');//同Object.defineProperty /** * assignValue方法和assignMergeValue的基本實現,不對值進行檢查 * * @private * @param {Object} object 需要修改的對象. * @param {string} key 賦值的key. * @param {*} value 賦值的value. */ function baseAssignValue(object, key, value) { if (key == '__proto__' && defineProperty) {//如果給__proto__賦值,使用defineProperty賦值 defineProperty(object, key, { 'configurable': true, 'enumerable': true, 'value': value, 'writable': true }); } else {//直接賦值 object[key] = value; } } module.exports = baseAssignValue;
assignValue
//_assignValue.js var baseAssignValue = require('./_baseAssignValue'),//baseAssignValue方法 eq = require('./eq');//判斷是否相等 var objectProto = Object.prototype;//對象的原型 var hasOwnProperty = objectProto.hasOwnProperty;//原生hasOwnProperty方法 /** * 對對象進行賦值,如果這個值不和本身對象中對象屬性的值相同的話 * * @private * @param {Object} object 需要修改的對象. * @param {string} key 輔助的key. * @param {*} value 賦值的value. */ function assignValue(object, key, value) { var objValue = object[key];//對象中對應屬性的值 if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || (value === undefined && !(key in object))) {//如果屬性不存在或者和本身的屬性不相等,進行賦值操作 baseAssignValue(object, key, value); } } module.exports = assignValue;
然后再看zipObject就比較清晰了
//zipObject.js var assignValue = require('./_assignValue'),//賦值函數 baseZipObject = require('./_baseZipObject');//baseZipObject方法 /** * 接收兩個數組轉化為對象,將第一個數組作為對象的屬性,第二個作為對象的值,返回這個對象 * * @param {Array} [props=[]] 屬性名. * @param {Array} [values=[]] 屬性值. * @returns {Object} 返回新的對象. * @example * * _.zipObject(['a', 'b'], [1, 2]); * // => { 'a': 1, 'b': 2 } */ function zipObject(props, values) { return baseZipObject(props || [], values || [], assignValue);//不解釋 } module.exports = zipObject;
_.zipObjectDeep([props=[]], [values=[]])
這個方法和_.zipObject很像,除了它支持使用屬性的路徑進行賦值
//zipObjectDeep.js var baseSet = require('./_baseSet'),//賦值函數,支持使用屬性路徑(暫時不分析) baseZipObject = require('./_baseZipObject');//baseZipObject方法 /** * * * @static * @memberOf _ * @since 4.1.0 * @category Array * @param {Array} [props=[]] 屬性名. * @param {Array} [values=[]] 屬性值. * @returns {Object} 返回新的對象. * @example * * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } */ function zipObjectDeep(props, values) { return baseZipObject(props || [], values || [], baseSet);//不解釋 } module.exports = zipObjectDeep;
_.zipWith([arrays], [iteratee=_.identity])
//zipWith.js var baseRest = require('./_baseRest'),//創建具備rest參數的方法 unzipWith = require('./unzipWith');//unzipWith方法。 /** * 這個方法和_.zip很像,除了它接收一個遍歷器決定怎么結合這些重組的元素,遍歷器接收一個rest參數,表示每個分組中對應元素(...group) * * @param {...Array} [arrays] 需要處理的數組. * @param {Function} [iteratee=_.identity] 遍歷器,決定怎么結合這些元素 * grouped values. * @returns {Array} 返回收起之后的數組. * @example * * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { * return a + b + c; * }); * // => [111, 222] */ var zipWith = baseRest(function(arrays) {//創建使用rest參數的方法 var length = arrays.length,//參數長度 iteratee = length > 1 ? arrays[length - 1] : undefined;//如果參數超過一個,遍歷器為最后一個參數 iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;//如果遍歷不為function,則為undefined return unzipWith(arrays, iteratee);//調用unzipWith方法,並將結果作為返回值返回。 }); module.exports = zipWith;
數組部分完結了,這些方法包含了很多對原生方法的重寫,以及對數組的的各種遍歷計算重組,通過學習這些方法感覺對數組的使用有了更深刻的認識。所以。。。繼續加油吧。。。!