Higher-Order Functions
Functions that operate on other functions, either by taking them as arguments or by returning them, are called higher-order functions.
we can have functions that create new functions.
function greaterThan(n) {return m => m > n;}let greaterThan10 = greaterThan(10);console.log(greaterThan10(11));// → true
we can have functions that change other functions.
function noisy(f) {return (...args) => {console.log("calling with", args);let result = f(...args);console.log("called with", args, ", returned", result);return result;};}noisy(Math.min)(3, 2, 1);// → calling with [3, 2, 1]// → called with [3, 2, 1] , returned 1
We can even write functions that provide new types of control flow.
function unless(test, then) {if (!test) then();}repeat(3, n => {unless(n % 2 == 1, () => {console.log(n, "is even");});});// → 0 is even// → 2 is even
forEach
There is a built-in array method, forEach, that provides something like a for/of loop as a higher-order function.
["A", "B"].forEach(l => console.log(l));// → A// → B
filter
function filter(array, test) {let passed = [];for (let element of array) {if (test(element)) {passed.push(element);}}return passed;}console.log(filter(SCRIPTS, script => script.living)); // script.living的值为true或false// → [{name: "Adlam", …}, …]console.log(SCRIPTS)console.log(SCRIPTS.filter(s => s.direction == "ttb"));
map
let arr = [{name: "Adlam", age:1},{name: "Caucasian Albanian", age:1},{name: "Ahom",age:1},{name: "Arabic", age:1}]console.log(arr.map(item => item.name))
reduce(归纳)
function reduce(array, combine, start) {let current = start;for (let element of array) {current = combine(current, element);}return current;}console.log(reduce([1, 2, 3, 4], (a, b) => a + b, 0));// → 10// The method will take the first element of the array as its start value// and start reducing at the second element.console.log([1, 2, 3, 4].reduce((a, b) => a + b));// → 10
some
// 有一个符合条件就返回true,所有都不符合返回falseconst array = [1, 2, 3, 4, 5];// checks whether an element is evenconst even = (element) => element % 2 === 0;console.log(array.some(even));// expected output: true
codePointAt
// Two emoji characters, horse and shoelet horseShoe = "🐴👟";console.log(horseShoe.length);// → 4console.log(horseShoe[0]);// → (Invalid half-character)console.log(horseShoe.charCodeAt(0));// → 55357 (Code of the half-character)console.log(horseShoe.codePointAt(0));// → 128052 (Actual code for horse emoji)let roseDragon = "🌹🐉";for (let char of roseDragon) {console.log(char);}// → 🌹// → 🐉
findIndex
const array1 = [5, 12, 8, 130, 44];const isLargeNumber = (element) => element > 13;console.log(array1.findIndex(isLargeNumber)); // 找不到返回-1// expected output: 3
Exercises
Flattening
let arrays = [[1, 2, 3], [4, 5], [6]]console.log(arrays.reduce((a,b) => a.concat(b)))// → [1, 2, 3, 4, 5, 6]
Your own loop
function loop(start, test, update, body) {for (let value = start; test(value); value = update(value)) {body(value);}}loop(3, n => n > 0, n => n - 1, console.log);// → 3// → 2// → 1
Everything
// 用for循环实现function every(array, test) {for(let i of array) {if (!test(i)){return false}}return true}// 用some实现function every(array, test) {return !array.some(element => !test(element))}console.log(every([1, 3, 5], n => n < 10));// → trueconsole.log(every([2, 4, 16], n => n < 10));// → falseconsole.log(every([], n => n < 10));// → true
