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.

  1. function greaterThan(n) {
  2. return m => m > n;
  3. }
  4. let greaterThan10 = greaterThan(10);
  5. console.log(greaterThan10(11));
  6. // → true

we can have functions that change other functions.

  1. function noisy(f) {
  2. return (...args) => {
  3. console.log("calling with", args);
  4. let result = f(...args);
  5. console.log("called with", args, ", returned", result);
  6. return result;
  7. };
  8. }
  9. noisy(Math.min)(3, 2, 1);
  10. // → calling with [3, 2, 1]
  11. // → called with [3, 2, 1] , returned 1

We can even write functions that provide new types of control flow.

  1. function unless(test, then) {
  2. if (!test) then();
  3. }
  4. repeat(3, n => {
  5. unless(n % 2 == 1, () => {
  6. console.log(n, "is even");
  7. });
  8. });
  9. // → 0 is even
  10. // → 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.

  1. ["A", "B"].forEach(l => console.log(l));
  2. // → A
  3. // → B

filter

  1. function filter(array, test) {
  2. let passed = [];
  3. for (let element of array) {
  4. if (test(element)) {
  5. passed.push(element);
  6. }
  7. }
  8. return passed;
  9. }
  10. console.log(filter(SCRIPTS, script => script.living)); // script.living的值为true或false
  11. // → [{name: "Adlam", …}, …]
  12. console.log(SCRIPTS)
  13. console.log(SCRIPTS.filter(s => s.direction == "ttb"));

map

  1. let arr = [{name: "Adlam", age:1},
  2. {name: "Caucasian Albanian", age:1},
  3. {name: "Ahom",age:1},
  4. {name: "Arabic", age:1}]
  5. console.log(arr.map(item => item.name))

reduce(归纳)

  1. function reduce(array, combine, start) {
  2. let current = start;
  3. for (let element of array) {
  4. current = combine(current, element);
  5. }
  6. return current;
  7. }
  8. console.log(reduce([1, 2, 3, 4], (a, b) => a + b, 0));
  9. // → 10
  10. // The method will take the first element of the array as its start value
  11. // and start reducing at the second element.
  12. console.log([1, 2, 3, 4].reduce((a, b) => a + b));
  13. // → 10

some

  1. // 有一个符合条件就返回true,所有都不符合返回false
  2. const array = [1, 2, 3, 4, 5];
  3. // checks whether an element is even
  4. const even = (element) => element % 2 === 0;
  5. console.log(array.some(even));
  6. // expected output: true

codePointAt

  1. // Two emoji characters, horse and shoe
  2. let horseShoe = "🐴👟";
  3. console.log(horseShoe.length);
  4. // → 4
  5. console.log(horseShoe[0]);
  6. // → (Invalid half-character)
  7. console.log(horseShoe.charCodeAt(0));
  8. // → 55357 (Code of the half-character)
  9. console.log(horseShoe.codePointAt(0));
  10. // → 128052 (Actual code for horse emoji)
  11. let roseDragon = "🌹🐉";
  12. for (let char of roseDragon) {
  13. console.log(char);
  14. }
  15. // → 🌹
  16. // → 🐉

findIndex

  1. const array1 = [5, 12, 8, 130, 44];
  2. const isLargeNumber = (element) => element > 13;
  3. console.log(array1.findIndex(isLargeNumber)); // 找不到返回-1
  4. // expected output: 3

Exercises

Flattening

  1. let arrays = [[1, 2, 3], [4, 5], [6]]
  2. console.log(arrays.reduce((a,b) => a.concat(b)))
  3. // → [1, 2, 3, 4, 5, 6]

Your own loop

  1. function loop(start, test, update, body) {
  2. for (let value = start; test(value); value = update(value)) {
  3. body(value);
  4. }
  5. }
  6. loop(3, n => n > 0, n => n - 1, console.log);
  7. // → 3
  8. // → 2
  9. // → 1

Everything

  1. // 用for循环实现
  2. function every(array, test) {
  3. for(let i of array) {
  4. if (!test(i)){
  5. return false
  6. }
  7. }
  8. return true
  9. }
  10. // 用some实现
  11. function every(array, test) {
  12. return !array.some(element => !test(element))
  13. }
  14. console.log(every([1, 3, 5], n => n < 10));
  15. // → true
  16. console.log(every([2, 4, 16], n => n < 10));
  17. // → false
  18. console.log(every([], n => n < 10));
  19. // → true