-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
我愿在心与心之间架起一道小桥,哪怕只是几块垫脚的青石板也好,将我们琐屑凌乱的生命连接。
----<破解幸福密码>
介绍
concat 函数类似于 ES 规范中的函数作用,用于进行数组拼接。
只是 lodash 在实现的过程中,不断践行自建基石的方针,也做了一些判断处理。
依赖
数组拷贝 copyArray
这个方法被用到,主要是考虑对原数组的保护。
/**
* Copies the values of `source` to `array`.
*
* @private
* @param {Array} source The array to copy values from.
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
function copyArray(source, array) {
var index = -1,
length = source.length;
// 对array的存在性做一下判断
array || (array = Array(length));
while (++index < length) {
array[index] = source[index];
}
return array;
}
module.exports = copyArray;数组后推入 arrayPush
继续自创push操作,通过操作数组下标进行赋值。
/**
* Appends the elements of `values` to `array`.
*
* @private
* @param {Array} array The array to modify.
* @param {Array} values The values to append.
* @returns {Array} Returns `array`.
*/
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
module.exports = arrayPush;
基础的数组扁平化操作 baseFlatten 👈 (划重点啦)
明显数组和类数组的 arguments 对象,可以通过遍历来展平。
另外在 ES6 中,可以设置 Symbol.isConcatSpreadable 的属性来表示该对象是否可以被展平。 Symbol.isConcatSpreadable 的值如果被设置为真值时,该对象是可以被展平的。
let b = {0: 1, 1: 2, length: 2}
b[Symbol.isConcatSpreadable]
// undefined, 默认无定义
console.log([].concat(b))
// [{…}],没取出其中元素
b[Symbol.isConcatSpreadable] = true
console.log([].concat(b))
// [1, 2],可以被展平
var arrayPush = require('./_arrayPush'),
// 可扁平化判断
isFlattenable = require('./_isFlattenable');
/**
* The base implementation of `_.flatten` with support for restricting flattening.
*
* @private
* @param {Array} array The array to flatten.
* @param {number} depth The maximum recursion depth.
* @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
* @param {Array} [result=[]] The initial result value.
* @returns {Array} Returns the new flattened array.
*/
function baseFlatten(array, depth, predicate, isStrict, result) {
var index = -1,
length = array.length;
predicate || (predicate = isFlattenable); // 预检查函数,不传指定为 isFlattenable
result || (result = []); // 期望放到指定的数组里,不传默认为一个空数组
while (++index < length) {
var value = array[index];
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// 递归扁平化操作
// Recursively flatten arrays (susceptible to call stack limits).
baseFlatten(value, depth - 1, predicate, isStrict, result);
} else {
arrayPush(result, value);
}
} else if (!isStrict) {
// 非严格模式下,只做一层扁平化
result[result.length] = value;
}
}
return result;
}
module.exports = baseFlatten;
源码
/**
* Creates a new array concatenating `array` with any additional arrays
* and/or values.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to concatenate.
* @param {...*} [values] The values to concatenate.
* @returns {Array} Returns the new concatenated array.
* @example
*
* var array = [1];
* var other = _.concat(array, 2, [3], [[4]]);
*
* console.log(other);
* // => [1, 2, 3, [4]]
*
* console.log(array);
* // => [1]
*/
function concat() {
var length = arguments.length;
if (!length) {
return [];
}
// 赋值已保护传入参数
var args = Array(length - 1),
array = arguments[0],
index = length;
while (index--) {
args[index - 1] = arguments[index];
}
// 对参数列表做了一级扁平化处理
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}
module.exports = concat;
总结
lodash工具函数充分考虑了对传入参数的保护,尽可能小的影响参数。lodash通过一些选项判断赋予函数更高的自由度和容错率。
引用
本文使用「 署名 4.0 国际」创作共享协议。
本文同步发布于Littlewin's Blog,欢迎多多交流。