JavaScript 高阶函数介绍

若是你正在学习或使用 JavaScript, 那么必定遇到过高级函数这个术语。听起来很高级复杂,其实否则。javascript

First-Class Functions

JavaScript 将函数做为一等公民。这是由于函数是对象。html

在 JavaScript 中,函数是一种特殊类型的对象。它们是 Function 对象。java

function greeting() {
  console.log('Hello World');
}

greeting();	// 'Hello World'
复制代码

为了证实函数是对象,咱们能够这样:数组

greeting.lang = 'English';

console.log(greeting.lang);		// 'English'
复制代码

Note——虽然这种写法在 JavaScript 种是彻底有效的,但被认为是有害的。不该该向函数对象添加随机属性,若是须要,请使用对象。函数

在 JavaScript 中,你能够将它们做为参数传递给其余函数(回调),将它们分配给变量并传递给其余函数等等。这也是函数被称为一等公民的缘由。学习

将函数赋值给变量

在 JavaScript 中,咱们能够将函数赋值给变量。测试

const square = function(x) {
  return x * x;
}

square(5);
复制代码

将函数做为参数传递

咱们能够将函数做为参数传递给其余函数。ui

function formalGreeting() {
  console.log("How are you?");
}

function casualGreeting() {
  console.log("What's up?")
}

function greet(type, greetFormal, greetCasual) {
  if(type === 'formal') {
    greetFormal();
  } else if(type === 'casual') {
    greetCasual();
  }
}

// prints 'What's up?'
greet('casual', formalGreeting, casualGreeting);
复制代码

如今咱们已经知道一等公民是什么,让咱们深刻理解 JavaScript 中的高阶函数。this

高阶函数

高阶函数是对其余函数进行操做的函数,能够将它们做为参数或返回它们。 简单来讲,高阶函数是一个函数,它接收函数做为参数或将函数做为输出返回。spa

例如,Array.prototype.map,Array.prototype.filter 和 Array.prototype.reduce 是 JavaScript 中内置的一些高阶函数。

简单介绍下这些内置高阶函数,并与不使用高阶函数的方案做下对比。

Array.prototype.map

map() 方法建立一个新数组,其结果是该数组中的每一个元素都调用一个提供的函数后返回的结果。

语法

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // Return element for new_array 
}[, thisArg])
复制代码

传递给 map() 的回调函数接受三个参数,分别是 currentValue, index(可选), array(可选),除了 callback 外,还能够接受 this(可选)值,做为执行 callback 函数是使用的 this 值。

例子

给定一个数字数组,想要建立一个新数组,其每一个元素是数组的两倍。

不使用高阶函数 map
const arr1 = [1, 2, 3];
const arr2 = [];
for(let i = 0; i < arr1.length; i++) {
  arr2.push(arr1[i] * 2);
}
// prints [ 2, 4, 6 ]
console.log(arr2);
复制代码
使用高阶函数 map
const arr1 = [1, 2, 3];
const arr2 = arr1.map(item => item * 2);
console.log(arr2);
复制代码

Array.prototype.filter

filter() 方法建立一个新数组, 其包含经过所提供函数实现的测试的全部元素

语法

var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
复制代码

传递给 filter() 的回调函数接受的参数和 map 相同。

例子

给定一个包含姓名和年龄属性的对象的数组,建立一个只包含年龄大于18的数组。

不使用高阶函数 filter
const persons = [
  { name: 'Peter', age: 16 },
  { name: 'Mark', age: 18 },
  { name: 'John', age: 27 },
  { name: 'Jane', age: 14 },
  { name: 'Tony', age: 24},
];
const fullAge = [];
for(let i = 0; i < persons.length; i++) {
  if(persons[i].age >= 18) {
    fullAge.push(persons[i]);
  }
}
console.log(fullAge);
复制代码
使用高阶函数 filter
const persons = [
  { name: 'Peter', age: 16 },
  { name: 'Mark', age: 18 },
  { name: 'John', age: 27 },
  { name: 'Jane', age: 14 },
  { name: 'Tony', age: 24},
];
const fullAge = persons.filter(person => person.age >= 18);
console.log(fullAge);
复制代码

Array.prototype.reduce

reduce() 方法对数组中的每一个元素执行一个提供的 reducer 函数(升序执行),将其结果汇总为单个返回值。

语法

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
复制代码

reducer 函数接收4个参数:

  1. Accumulator (acc) (累计器)
  2. Current Value (cur) (当前值)
  3. Current Index (idx) (当前索引)
  4. Source Array (src) (源数组)

reducer 函数的返回值分配给累计器,该返回值在数组的每一个迭代中被记住,并最后成为最终的单个结果值。

若是有 initialValue, accumulator 等于 initialValue,currentValue 等于数组第一个元素。

若是没有有 initialValue, accumulator 等于 数组第一个元素,currentValue 等于数组第二个元素。

例子

求给定数组的和

不使用高阶函数 reduce
const arr = [5, 7, 1, 8, 4];
let sum = 0;
for(let i = 0; i < arr.length; i++) {
  sum = sum + arr[i];
}
// prints 25
console.log(sum);
复制代码
使用高阶函数 reduce
const arr = [5, 7, 1, 8, 4];
const sum = arr.reduce(function(accumulator, currentValue) {
  return accumulator + currentValue;
});
// prints 25
console.log(sum);
复制代码

建立本身的高阶函数

到目前为止,咱们介绍了 JavaScript 中内置的各类高阶函数。如今让咱们建立本身的高阶函数。

假设 JavaScript 没有原生 map 方法。 咱们能够本身构建它。

假设有一个字符串数组,但愿将此数组转换为整数数组,其中每一个元素表示原始数组中字符串的长度。

function mapForEach(arr, fn) {
  const newArray = [];
  for(let i = 0; i < arr.length; i++) {
    newArray.push(
      fn(arr[i])
    );
  }
  return newArray;
}
const lenArray = mapForEach(strArray, function(item) {
  return item.length;
});
// prints [ 10, 6, 3, 4, 1 ]
console.log(lenArray);
复制代码

总结

咱们已经了解了高阶函数和一些内置的高阶函数。 咱们还学习了如何建立本身的高阶函数。

简而言之,高阶函数是一个函数,能够接收函数做为参数,甚至能够返回一个函数。

参考资料

相关文章
相关标签/搜索