原文首发于Lodash源码讲解
这是我们阅读Lodash源码的第3篇博客,在这篇文章里我们来学习一下Lodash的compact
方法。
compact
函数内部没有依赖别的函数,让我们先来看一下compact
函数的源码。
/**
* Creates an array with all falsey values removed. The values `false`, `null`,
* `0`, `""`, `undefined`, and `NaN` are falsey.
*
* @since 0.1.0
* @category Array
* @param {Array} array The array to compact.
* @returns {Array} Returns the new array of filtered values.
* @example
*
* compact([0, 1, false, 2, '', 3])
* // => [1, 2, 3]
*/
function compact(array) {
let resIndex = 0
const result = []
if (array == null) {
return result
}
for (const value of array) {
if (value) {
result[resIndex++] = value
}
}
return result
}
export default compact
首先我们先说一下这个函数的作用,这个函数接收一个数组作为参数;然后将数组中所有通过布尔转换可以变为false
的值去除;从而生成一个新的数组。
那么那些值通过布尔转换会变为false
呢;这些值有:0
,""
,false
,null
,undefined
,NaN
。
因为这个函数比较简单,我们就不划分步骤了,直接进行讲解;首先我们初始化了两个变量,resIndex
用来表示我们返回的数组的索引;result
是我们新创建的一个数组,这个数组就是我们要返回的数组;接下来,如果传递的数组为空,我们直接返回一个空的数组;接下来就是使用ES6
新的语法,for...of
对传递的数组进行循环,将能够通过布尔转化为false
的值去除,然后就获取到了我们想要的结果。
那么,接下来我们首先把这个源码部分实现一遍;虽然简单,但是还是要自己敲一遍代码的;切记不要眼高手低。compact是我自己又重新实现一遍的代码。
接下来我们考虑一下,如果我们不使用for...of
来循环数组,而是使用数组的map
方法,或者是使用while
进行数组的循环;它们的效率有多大的差异?让我们来实践一下,首先是使用map
方法,我们使用如下的代码来进行测试:
// 使用数组原生的map方法
function compact(array) {
// 判断array是否为空
if(array == null) {
return [];
}
let result = [];
array.map((value) => {
if(value) {
result.push(value);
}
});
return result;
}
再接着我们使用while
进行数组的循环,使用如下的代码进行测试:
// 使用while进行数组的循环
function compact(array) {
// 判断array是否为空
if(array == null) {
return [];
}
let result = [];
let index = 0;
let resIndex = 0;
let value;
const length = array.length;
while(index < length) {
value = array[index];
if(value) {
result[resIndex++] = value;
}
index++;
}
return result;
}
我将这两个方法都添加到之前的那个例子中了,大家可以点击这里查看。
接下来我们就要进行性能的测试了,我写了一个测试的用例;大家可以点击这里查看。经过多次测试发现,使用lodash的compact
方法和使用while
进行数组循环的compact方法的性能都还是不错的,使用map
进行数组循环的compact方法性能最差;但是使用map
方法的compact方法代码量是比较少的。
性能比较的图如下图所示:
- lodash的
compact
方法性能比较好的一次测试:
- 使用
while
进行数组循环的compact方法性能比较好的一次测试:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。