Javascript练习,手写Lodash内置函数(2)

目录

一.前言

1.什么是lodash

2.手写Lodash内置函数的好处 

二.今天的练习

1.手写differenceWith函数:differenceWith(array,values,comparator)

1.1:函数功能

1.2:参数说明

1.3:返回值

1.4:实现代码

1.5:实现原理

1.6:测试用例

2.手写drop函数:drop(array,n=1)

1.1:函数功能

2.2:参数说明

2.3:返回值

2.4:实现代码

2.5:实现原理

2.6:测试用例

3.手写dropRight函数:dropRight(array,n=1)

3.1:函数功能

3.2:参数说明

3.3:返回值

3.4:实现代码

3.5:实现原理

3.6:测试用例

4.手写dropRightWhile函数:dropRightWhile(array,[predicate=._identity])

4.1:函数功能

4.2:参数说明

4.3:返回值

4.4:实现代码

4.5:实现原理

4.6:测试用例

5.手写fill函数:fill(array,value,start=0,end=array.length)

5.1:函数功能

5.2:参数说明

5.3:返回值

5.4:实现代码

5.5:实现原理

5.6:测试用例


一.前言

1.什么是lodash

相信学前端的小伙伴应该对Lodash是比较了解的,Lodash是一个实用的 JavaScript 工具库,提供了很多常用的工具函数,以简化 JavaScript 编程。Lodash提供了许多对数组、数字、字符串和对象等进行操作的实用工具函数,这使得 JavaScript 开发更加高效、简便、可读、可维护。

Lodash的好处:

  • 节省编程时间:通过提供封装好的优化的工具方法,减少编写各种常见代码的时间。
  • 更加安全:通过 Lodash 提供的高抽象性 API,减少使用内置 JavaScript API 带来的人为失误的可能性。
  • 更快的性能:Lodash 经过了严格的测试和针对不同环境的优化,性能要比自己实现的方法更高。

2.手写Lodash内置函数的好处 

对于初学者而言,常常会因为学完Javascriptes6的语法却没地方练手而困扰,这样就容易造成学完就忘的情况,而原生Javascript对于前端学习者来说是非常重要的,如果没有打好基础以后就会造成很多问题,遇到问题很难独立解决,以及面试时要求手写一些底层原理代码等等,当你手写完Lodash内置函数后,你的基本功就会变得扎实,后续的学习也会变得豁然开朗。

二.今天的练习

1.手写differenceWith函数:differenceWith(array,values,comparator)

1.1:函数功能

这个方法类似difference ,除了它接受一个 comparator (注:比较器),它调用比较arrayvalues中的元素。 结果值是从第一数组中选择。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:实现原理

  1. 在函数中先复制传入的数组 array,避免修改原有数组;
  2. 定义一个变量 i,表示从右向左遍历数组 array 的下标,初始化为数组最后一个元素的下标;
  3. 根据断言函数 predicate 的类型,构造相应的条件判断,进行处理不同类型的断言函数;
  4. 根据数组遍历,运用条件判断集合,从尾部判断元素是否符合条件,如果符合就删除该元素,直到找到第一个不符合条件的元素;
  5. 返回删除符合条件元素之后的新数组 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:实现原理

也就是对数组进行循环遍历替换即可

5.6:测试用例

猜你喜欢

转载自blog.csdn.net/m0_64642443/article/details/131299655