目录
1.手写differenceWith函数:differenceWith(array,values,comparator)
3.手写dropRight函数:dropRight(array,n=1)
4.手写dropRightWhile函数:dropRightWhile(array,[predicate=._identity])
5.手写fill函数:fill(array,value,start=0,end=array.length)
一.前言
1.什么是lodash
相信学前端的小伙伴应该对Lodash是比较了解的,Lodash是一个实用的 JavaScript 工具库,提供了很多常用的工具函数,以简化 JavaScript 编程。Lodash提供了许多对数组、数字、字符串和对象等进行操作的实用工具函数,这使得 JavaScript 开发更加高效、简便、可读、可维护。
Lodash的好处:
- 节省编程时间:通过提供封装好的优化的工具方法,减少编写各种常见代码的时间。
- 更加安全:通过 Lodash 提供的高抽象性 API,减少使用内置 JavaScript API 带来的人为失误的可能性。
- 更快的性能:Lodash 经过了严格的测试和针对不同环境的优化,性能要比自己实现的方法更高。
2.手写Lodash内置函数的好处
对于初学者而言,常常会因为学完Javascript和es6的语法却没地方练手而困扰,这样就容易造成学完就忘的情况,而原生Javascript对于前端学习者来说是非常重要的,如果没有打好基础以后就会造成很多问题,遇到问题很难独立解决,以及面试时要求手写一些底层原理代码等等,当你手写完Lodash内置函数后,你的基本功就会变得扎实,后续的学习也会变得豁然开朗。
二.今天的练习
1.手写differenceWith函数:differenceWith(array,values,comparator)
1.1:函数功能
这个方法类似difference ,除了它接受一个 comparator
(注:比较器),它调用比较array
,values
中的元素。 结果值是从第一数组中选择。comparator 调用参数有两个:(arrVal, othVal)。
1.2:参数说明
array
(Array): 要检查的数组。
[values]
(...Array): 排除的值。
[comparator]
(Function): comparator 调用每个元素。
1.3:返回值
(Array): 返回一个过滤值后的新数组。
1.4:实现代码
function differenceWith(arr1, arr2, comparator) {
return arr1.filter((item1) => {
// 检查第二个数组中是否存在与 item1 匹配的项
// 如果不存在,则返回 true 保留 item1
// 否则,返回 false,item1 将被忽略
return !arr2.some((item2) => comparator(item1, item2))
})
}
1.5:实现原理
具体实现是,对
arr1
进行filter
操作,对于每个元素item1
,使用arr2.some
遍历arr2
,查找是否存在一个元素item2
,使得comparator(item1, item2)
返回true
。如果存在这样的元素item2
,则说明item1
在arr2
中也存在,应该被过滤掉;否则item1
在arr2
中不存在,应该被保留下来。
1.6:测试用例
2.手写drop函数:drop(array,n=1)
1.1:函数功能
创建一个切片数组,去除array
前面的n
个元素。(n
默认值为1。)
2.2:参数说明
array
(Array): 要查询的数组。
[n=1]
(number): 要去除的元素个数。
2.3:返回值
(Array): 返回array
剩余切片。
2.4:实现代码
function drop(array, n = 1) {
if (!Array.isArray(array)) {
return []
}
return array.slice(n)
}
2.5:实现原理
就是运用了原生的slice切片函数
2.6:测试用例
3.手写dropRight函数:dropRight(array,n=1)
3.1:函数功能
创建一个切片数组,去除array
尾部的n
个元素。(n
默认值为1。)
3.2:参数说明
array
(Array): 要查询的数组。
[n=1]
(number): 要去除的元素个数。
3.3:返回值
(Array): 返回array
剩余切片。
3.4:实现代码
function dropRight(array, n = 1) {
if (!Array.isArray(array)) {
return []
}
const length = array.length
if (n >= length) {
return []
}
return array.slice(0, length - n)
}
3.5:实现原理
也是一样对slice切片函数的运用
3.6:测试用例
4.手写dropRightWhile函数:dropRightWhile(array,[predicate=._identity])
4.1:函数功能
创建一个切片数组,去除array
中从 predicate
返回假值开始到尾部的部分。predicate 会传入3个参数: (value, index, array)。意思就是predicate参数是一个限制条件,根据此限制条件来进行切片处理,它可以是一个函数,对象,数组,字符串
4.2:参数说明
array
(Array): 要查询的数组。
[predicate=_.identity]
(Function): 这个函数会在每一次迭代调用。
4.3:返回值
(Array): 返回array
剩余切片。
4.4:实现代码
function dropRightWhile(array, predicate) {
const result = array.slice()
let i = result.length - 1
// 根据不同的参数类型构造相应的判定函数
if (typeof predicate === 'function') {
while (i >= 0 && predicate(result[i], i, result)) {
result.pop()
i--
}
} else if (Array.isArray(predicate)) {
while (i >= 0 && result[i][predicate[0]] === predicate[1]) {
result.pop()
i--
}
} else if (typeof predicate === 'object') {
const keys = Object.keys(predicate)
while (i >= 0 && keys.every((key) => result[i][key] === predicate[key])) {
result.pop()
i--
}
} else if (typeof predicate === 'string') {
while (i >= 0 && result[i][predicate]) {
result.pop()
i--
}
}
return result
}
4.5:实现原理
- 在函数中先复制传入的数组
array
,避免修改原有数组;- 定义一个变量
i
,表示从右向左遍历数组array
的下标,初始化为数组最后一个元素的下标;- 根据断言函数
predicate
的类型,构造相应的条件判断,进行处理不同类型的断言函数;- 根据数组遍历,运用条件判断集合,从尾部判断元素是否符合条件,如果符合就删除该元素,直到找到第一个不符合条件的元素;
- 返回删除符合条件元素之后的新数组
result
。
4.6:测试用例
官方测试用例:
dropWhile函数和dropRightWhile函数的功能和实现是类似的,不同点是一个从头开始切,一个从尾开始切
5.手写fill函数:fill(array,value,start=0,end=array.length)
5.1:函数功能
使用 value
值来填充(替换) array
,从start
位置开始, 到end
位置结束(但不包含end
位置)。
Note: 这个方法会改变 array
(注:不是创建新数组)。
5.2:参数说明
array
(Array): 要填充改变的数组。
value
(*): 填充给 array
的值。
[start=0]
(number): 开始位置(默认0)。
[end=array.length]
(number):结束位置(默认array.length)。
5.3:返回值
(Array): 返回 array
。
5.4:实现代码
function fill(array, value, start = 0, end = array.length) {
for (let i = start; i < end; i++) {
array[i] = value
}
return array
}
5.5:实现原理
也就是对数组进行循环遍历替换即可