0%

JavaScript-高阶函数浅析

高阶函数

高阶函数英文叫 Higher-order function,它的定义很简单,就是至少满足下列一个条件的函数:

  • 函数作为返回值
  • 函数作为参数传递

也就是说高阶函数是对其他函数进行操作的函数,可以将它们作为参数传递,或者是返回函数。

函数作为参数传递

JavaScript 语言中内置了一些高阶函数,比如 Array.prototype.map,Array.prototype.filter 和 Array.prototype.reduce,它们接受一个函数作为参数,并使用这个函数作用到列表的每一个元素

Array.prototype.map

map() 函数返回一个新的数组,新数组中的元素是回调函数(callback)作用于指定数组中的元素后返回的结果。

  • 不会改变原始数组
1
array.map(function(currentValue,index,arr), thisValue)
  • function(currentValue, index,arr):必须。函数,数组中的每个元素都会执行这个函数
    • currentValue:必须。当前元素的值
    • 可选。当前元素的索引值
    • arr:可选。当前元素属于的数组对象
  • thisValue:可选。对象作为该执行回调时使用,传递给函数,用作 “this” 的值。如果省略了 thisValue ,”this” 的值为 “undefined”
1
2
3
4
5
6
7
const arr1 = [1, 3, 6, 9];
const arr2 = arr1.map(item => item * 2);

console.log( arr2 );
// [2, 6, 12, 18]
console.log( arr1 );
// [1, 3, 6, 9]

Array.prototype.filter

filter() 方法返回一个新数组, 新数组中的元素是通过检查指定数组中符合条件的所有元素。

  • 不会对空数组进行检测
  • 不会改变原始数组
1
array.filter(function(currentValue,index,arr), thisValue)
  • function(currentValue, index,arr):必须。函数,数组中的每个元素都会执行这个函数
    • currentValue:必须。当前元素的值
    • 可选。当前元素的索引值
    • arr:可选。当前元素属于的数组对象
  • thisValue:可选。对象作为该执行回调时使用,传递给函数,用作 “this” 的值。如果省略了 thisValue ,”this” 的值为 “undefined”

数组去重

1
2
3
4
5
6
7
8
9
const arr1 = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
const arr2 = arr1.filter( (element, index, self) => {
return self.indexOf( element ) === index;
});

console.log( arr2 );
// [1, 2, 3, 5, 4]
console.log( arr1 );
// [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]

Array.prototype.reduce

reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),回调函数(callback),将其结果汇总为单个返回值。除了 callback 之外还可以接受初始值 initialValue 值(可选)

  • 如果没有提供 initialValue,那么第一次调用 callback 函数时,accumulator 使用原数组中的第一个元素,currentValue 即是数组中的第二个元素。 在没有初始值的空数组上调用 reduce 将报错。

  • 如果提供了 initialValue,那么将作为第一次调用 callback 函数时的第一个参数的值,即 accumulator,currentValue 使用原数组中的第一个元素。

1
array.reduce(function(accumulator, currentValue, currentIndex, array){}, initialValue)
  • function(accumulator, currentValue, currentIndex, array):必须。函数
    • Accumulator (acc):累计器
    • Current Value (cur):当前值
    • Current Index (idx):当前索引 可选
    • Source Array (src):源数组 可选
  • initialValue:initialValue

数组求和

1
2
3
4
5
6
7
8
9
const arr = [0, 1, 2, 3, 4];
let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue;
});

console.log( sum );
// 10
console.log( arr );
// [0, 1, 2, 3, 4]

函数作为返回值输出

isType 函数

通过 Object.prototype.toString.call判断类型

1
2
3
4
5
6
7
const isType = type => obj => {
return Object.prototype.toString.call( obj ) === '[object ' + type + ']';
}

isType('String')('123') // true
isType('Array')([1, 2, 3]); // true
isType('Number')(123) // true

add 函数

一个常见的面试题,用 JS 实现一个无限累加的函数 add,示例如下:

1
2
3
4
add(1); // 1
add(1)(2); // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10

都是将函数作为返回值输出,然后接收新的参数并进行计算。

我们知道打印函数时会自动调用 toString()方法,函数 add(a) 返回一个闭包 sum(b),函数 sum() 中累加计算 a = a + b,只需要重写sum.toString()方法返回结果值 a 就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add(a) {
function sum(b) {
a = a + b; // 求和
return sum; // 返回求和函数
}
// 重写toString()方法
sum.toString = function () {
return a;
}
return sum; // 返回求和函数
}

add(1); // 1
add(1)(2); // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10

参考

https://muyiy.cn/blog/6/6.1.html

-------------本文结束感谢您的阅读-------------