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);
複製代碼

總結

咱們已經瞭解了高階函數和一些內置的高階函數。 咱們還學習瞭如何建立本身的高階函數。

簡而言之,高階函數是一個函數,能夠接收函數做爲參數,甚至能夠返回一個函數。

參考資料

相關文章
相關標籤/搜索