zoukankan      html  css  js  c++  java
  • JavaScript学习-高阶函数

    一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

    一个例子

    function add(x, y, f) {
        return f(x) + f(y);
    }
    
    var x = add(-5, 6, Math.abs); // 11
    console.log(x);

    Map

    map()方法定义在JavaScript的Array中

    传入我们自己的函数,就得到了一个新的Array作为结果

    将数组里面的元素,按照传入map里面的函数,进行转换

    function pow(x) {
        return x * x;
    }
    
    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
    console.log(results);

    把Array的所有数字转为字符串

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']

    Reduce

    有点难说,看表达式吧,就是将当前元素和下一个进行累积计算

    [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)

    假设先计算A = f(x1,x2)

    再计算B = f(A,x3)

    再计算f(B,x4)

    对array求和

    var arr = [1, 3, 5, 7, 9];
    arr.reduce(function (x, y) {
        return x + y;
    }); // 25

    filter

    它用于把Array的某些元素过滤掉,然后返回剩下的元素

    sort

    var arr = [10, 20, 1, 2];
    
    arr.sort(function (x, y) {
        if (x < y) {
            return -1;
        }
        if (x > y) {
            return 1;
        }
        return 0;
    });
    console.log(arr); // [1, 2, 10, 20]

    闭包

    这个概念有点难懂,而且暂时没怎么用到过

    简单来说 就是返回一个函数然后延迟执行 ,但是又不仅限如此

    function lazy_sum(arr) {
        var sum = function () {
            return arr.reduce(function (x, y) {
                return x + y;
            });
        }
        return sum;
    }
    
    
    //并没有求和,而是返回了一个求和函数
    var f = lazy_sum([1, 2, 3, 4, 5]); 
    
    //这时候才是调用
    f(); // 15

    这也是一个闭包的用法

    //前面一个括号是返回了一个函数,后面的(3)是函数调用
    (function (x) { return x * x }) (3);

    闭包实现的计数器....

    说实话不知道为什么不能直接实现一个计数器,说是为了使得x变成private,私有变量,因为js根本就没有private这种东西

    那可不可以说。。。为了省略private以及变量类型等东西,导致添加了很多复杂的东西去填补这些坑。

    function create_counter(initial) {
        var x = initial || 0;
        return {
            inc: function () {
                x += 1;
                return x;
            }
        }
    }

    其实,根本没法写一个带状态的函数。(自己试过了)

    只能写一个类,然而没法私有

    f = function(initial){
    
         //这样写,没有用,因为每次调用就是一个新的,根本没法实现计数的功能  
         var x = initial||0;
    
    
    }
    
    
    var cal{
    
      current:0;
      ins:function(){
      return current+=1;
    }
    
    
    }

    闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。

    箭头函数

    又是ES6的语法糖,说实话为了简便提供这么多语法糖还真的好吗

    箭头函数相当于匿名函数,并且简化了函数定义

    var arr = [10, 20, 1, 2];
    
    arr.sort((x, y) => {
        if(x<y){
         return -1;
       }
          if(x>y){
       return 1;
    
    }
    
    return 0;
    });
    console.log(arr); // [1, 2, 10, 20]

    生成器

    generator就是能够返回多次的“函数”

    因为generator可以在执行过程中多次返回,所以它看上去就像一个可以记住执行状态的函数

    用一个对象来保存状态,得这么写:

    //每次调用,返回不同状态下的fib值
    var fib = {
        a: 0,
        b: 1,
        n: 0,
        max: 5,
        next: function () {
            var
                r = this.a,
                t = this.a + this.b;
            this.a = this.b;
            this.b = t;
            if (this.n < this.max) {
                this.n ++;
                return r;
            } else {
                return undefined;
            }
        }
    };

    用生成器写

    解构赋值

    function* fib(max) {
        var
            t,
            a = 0,
            b = 1,
            n = 0;
        while (n < max) {
            yield a;
            [a, b] = [b, a + b];
            n ++;
        }
        return;
    }
    //max值为5的生成器
    fib(5)

    直接调用一个generator和调用函数不一样,fib(5)仅仅是创建了一个generator对象,还没有去执行它。

    调用generator对象有两个方法,一是不断地调用generator对象的next()方法

    var f = fib(5);
    f.next(); // {value: 0, done: false}
    f.next(); // {value: 1, done: false}
    f.next(); // {value: 1, done: false}
    f.next(); // {value: 2, done: false}
    f.next(); // {value: 3, done: false}
    f.next(); // {value: undefined, done: true}

    每次遇到yield x;就返回一个对象{value: x, done: true/false},然后“暂停”。

    返回的value就是yield的返回值,

    done表示这个generator是否已经执行结束了。

    如果done为true,则value就是return的返回值。undefined

    第二个方法是直接用for ... of循环迭代generator对象,这种方式不需要我们自己判断done

    for (var x of fib(10)) {
        console.log(x); // 依次输出0, 1, 1, 2, 3, ...
    }
  • 相关阅读:
    [DB] 数据库的连接
    JS leetcode 翻转字符串里的单词 题解分析
    JS leetcode 拥有最多糖果的孩子 题解分析,六一快乐。
    JS leetcode 搜索插入位置 题解分析
    JS leetcode 杨辉三角Ⅱ 题解分析
    JS leetcode 寻找数组的中心索引 题解分析
    JS leetcode 移除元素 题解分析
    JS leetcode 最大连续1的个数 题解分析
    JS leetcode 两数之和 II
    JS leetcode 反转字符串 题解分析
  • 原文地址:https://www.cnblogs.com/weizhibin1996/p/9274324.html
Copyright © 2011-2022 走看看