1、简述

高阶函数似乎是一种先进编程的的技术。然而,并不是。

高阶函数其实就是将函数作为参数或者返回值的函数。其中作为参数的函数一般是回调函数。

2、例子

(1)最简单的例子

大家都熟悉数组的sort方法。

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>高阶函数</title>
    </head>

    <body>
        <script type="text/javascript">
            let arr = [1,2,4,3];
            arr.sort((a,b)=>{return a-b})
            console.log(arr)
        </script>
    </body>

</html>

sort方法的参数就是一个函数(回调函数),这个回调函数决定了如何比较数组中的任意两个元素。

Array的sort方法源码实现(使用了插入排序和快速排序):

            function ArraySort(comparefn) {
                // 使用款速排序算法
                // 对于长度小于22的数组,使用插入排序算法

                //判断comparefn是不是一个函数
                var custom_compare = IS_FUNCTION(comparefn);

                function Compare(x, y) {
                    // 假设comparefn(若存在的话)是一致的比较函数。
                    // 如果不是,则假设假设comparefn函数是任意的(通过ECMA 15.4.4.11)
                    if(x === y) return 0;
                    if(custom_compare) {
                        // 不要直接调用comparefn以避免暴露内置的全局对象。.
                        return comparefn.call(null, x, y);
                    }
                    x = ToString(x);
                    y = ToString(y);
                    if(x == y) return 0;
                    else return x < y ? -1 : 1;
                };

                //插入排序
                function InsertionSort(a, from, to) {
                    for(var i = from + 1; i < to; i++) {
                        var element = a[i];
                        // Pre-convert the element to a string for comparison if we know
                        // it will happen on each compare anyway.
                        var key =
                            (custom_compare || % _IsSmi(element)) ? element : ToString(element);
                        // place element in a[from..i[
                        // binary search
                        var min = from;
                        var max = i;
                        // The search interval is a[min..max[
                        while(min < max) {
                            var mid = min + ((max - min) >> 1);
                            var order = Compare(a[mid], key);
                            if(order == 0) {
                                min = max = mid;
                                break;
                            }
                            if(order < 0) {
                                min = mid + 1;
                            } else {
                                max = mid;
                            }
                        }
                        // place element at position min==max.
                        for(var j = i; j > min; j--) {
                            a[j] = a[j - 1];
                        }
                        a[min] = element;
                    }
                }

                //快速排序
                function QuickSort(a, from, to) {
                    // 若数组长度小于22的话,使用插入排序。
                    if(to - from <= 22) {
                        InsertionSort(a, from, to);
                        return;
                    }
                    var pivot_index = $floor($random() * (to - from)) + from;
                    var pivot = a[pivot_index];
                    // Pre-convert the element to a string for comparison if we know
                    // it will happen on each compare anyway.
                    var pivot_key =
                        (custom_compare || % _IsSmi(pivot)) ? pivot : ToString(pivot);
                    // Issue 95: Keep the pivot element out of the comparisons to avoid
                    // infinite recursion if comparefn(pivot, pivot) != 0.
                    a[pivot_index] = a[from];
                    a[from] = pivot;
                    var low_end = from; // Upper bound of the elements lower than pivot.
                    var high_start = to; // Lower bound of the elements greater than pivot.
                    // From low_end to i are elements equal to pivot.
                    // From i to high_start are elements that haven't been compared yet.
                    for(var i = from + 1; i < high_start;) {
                        var element = a[i];
                        var order = Compare(element, pivot_key);
                        if(order < 0) {
                            a[i] = a[low_end];
                            a[low_end] = element;
                            i++;
                            low_end++;
                        } else if(order > 0) {
                            high_start--;
                            a[i] = a[high_start];
                            a[high_start] = element;
                        } else { // order == 0
                            i++;
                        }
                    }
                    QuickSort(a, from, low_end);
                    QuickSort(a, high_start, to);
                }

                var old_length = ToUint32(this.length);
                if(old_length < 2) return this;

                %
                RemoveArrayHoles(this);

                var length = ToUint32(this.length);

                // 将未定义的元素移动到数组的末尾.
                for(var i = 0; i < length;) {
                    if(IS_UNDEFINED(this[i])) {
                        length--;
                        this[i] = this[length];
                        this[length] = void 0;
                    } else {
                        i++;
                    }
                }

                QuickSort(this, 0, length);

                //如果this是一个数组,我们只改变了这个数组的长度。 如果this不是数组,则不允许设置此对象的长度,因为这可能会引入新的length属性。
                if(IS_ARRAY(this)) {
                    this.length = old_length;
                }

                return this;
            }

(2)字符换大写

实现一:

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>高阶函数</title>
    </head>

    <body>
        <script type="text/javascript">
            let arr = ['abc', 'def'],
                arrNew = [];
            for(let i = 0; i < arr.length; i++) {
                arrNew[i] = arr[i].toUpperCase()
            }
            console.log(arrNew)
        </script>
    </body>

</html>

实现二:

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>高阶函数</title>
    </head>

    <body>
        <script type="text/javascript">
            let arr = ['abc', 'def'],
                arrNew = [];
            arrNew = arr.map(val => {
                return val.toUpperCase()
            })
            console.log(arrNew)
        </script>
    </body>

</html>

(3)高阶函数实现

若代码中出现重复或者类似的代码,就可以使用高阶函数。如产生一个包含数字的字符串:

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>高阶函数</title>
    </head>

    <body>
        <script type="text/javascript">
            let digits = ''
            for (let i=0;i<10;i++) {
                digits += i
            }
            console.log(digits)
        </script>
    </body>

</html>

使用高阶函数实现:

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>高阶函数</title>
    </head>

    <body>
        <script type="text/javascript">
            let digits = ''
            function buildString(n, callback) {
                let val = '';
                for(let i = 0; i < n; i++) {
                    val += callback(i)
                }
                return val
            }
            digits = buildString(10, i => {
                return i
            })
            console.log(digits)
        </script>
    </body>

</html>

高阶函数简述 js的更多相关文章

  1. 【js】高阶函数是个什么?

    所谓高阶函数,就是函数中可以传入另一个函数作为参数的函数. 简单一张图,方便理解全文. function 高阶函数(函数){} 这是一个高阶函数,f是传入的函数作为参数. 其实高阶函数用的很多.其实平 ...

  2. js高阶函数

    我是一个对js还不是很精通的选手: 关于高阶函数详细的解释 一个高阶函数需要满足的条件(任选其一即可) 1:函数可以作为参数被传递 2:函数可以作为返回值输出 吧函数作为参数传递,这代表我们可以抽离一 ...

  3. [Node.js] 闭包和高阶函数

    原文地址:http://www.moye.me/2014/12/29/closure_higher-order-function/ 引子 最近发现一个问题:一部分写JS的人,其实对于函数式编程的概念并 ...

  4. js高阶函数应用—函数防抖和节流

    高阶函数指的是至少满足下列两个条件之一的函数: 1. 函数可以作为参数被传递:2.函数可以作为返回值输出: javaScript中的函数显然具备高级函数的特征,这使得函数运用更灵活,作为学习js必定会 ...

  5. js 高阶函数 闭包

    摘自  https://www.cnblogs.com/bobodeboke/p/5594647.html 建议结合另外一篇关于闭包的文章一起阅读:http://www.cnblogs.com/bob ...

  6. 理解运用JS的闭包、高阶函数、柯里化

    JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...

  7. JS高阶函数的理解(函数作为参数传递)

    JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...

  8. JS的闭包、高阶函数、柯里化

    本文原链接:https://cloud.tencent.com/developer/article/1326958 https://cloud.tencent.com/developer/articl ...

  9. 【重温基础】JS中的常用高阶函数介绍

    Ps. 晚上加班到快十点,回来赶紧整理整理这篇文章,今天老大给我推荐了一篇文章,我从写技术博客中收获到了什么?- J_Knight_,感受也是很多,自己也需要慢慢养成记录博客的习惯,即使起步艰难,难以 ...

随机推荐

  1. plsql查找不到带中文的纪录

    今天在另外的电脑用plsql查询不到带中文的记录 select * from test where name like '%测试%' 然后发现是系统的环境变量还没设置好所造成的.在系统变量加入如下变量 ...

  2. Jquery中的offset()和position()

    今天遇到这个偏移量的问题,特做此记录.以便日后查看. 先看看这两个方法的定义. offset(): 获取匹配元素在当前视口的相对偏移. 返回的对象包含两个整形属性:top 和 left.此方法只对可见 ...

  3. hdu 4815 Little Tiger vs. Deep Monkey(01背包)

    http://acm.hdu.edu.cn/showproblem.php?pid=4815 Description A crowd of little animals is visiting a m ...

  4. 利用css进行网页布局

    网页布局: 又称版式布局,是网页UI设计师将有限的视觉元素进行有机的排列组合,将理性的思维个性的化的表现出来,是一种具有个人艺术特色的视觉传达方式.传达信息的同时有美感.网页设计特点(相对纸媒来说). ...

  5. 使用 Fluent API 配置/映射属性和类型2

    1.将多个实体类映射到数据库中的一个表 要将多个实体映射到一个数据库表需要满足: a. 两个实体必须是一对一关系 b.两个实体共享一个主键 public class MyContext:DbConte ...

  6. DataSnap

    一. DataSnap REST - http://docwiki.embarcadero.com/RADStudio/Berlin/en/DataSnap_REST 1. URI Mapping: ...

  7. 鼠标右键怎么清除Catalyst Control Center

    开始→运行→regedit→找到HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\ACE→双击并修改其键值 可以删除 ...

  8. 自己定义控件(2.2):SurfaceView和SurfaceHolder

    本例需求及流程: Activity载入自己定义的SurfaceView-> SurfaceView 构造器中启动线程A.循环改变SurfaceView的x,y坐标,当x,y坐标到某点时设渐显标志 ...

  9. 剑指offer——矩阵覆盖(斐波那契变形)

    ****感觉都可以针对斐波那契写一个变形题目的集合了****** 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? cl ...

  10. Py之Crawler:利用python的爬虫功能实现从各种网站上(以百度贴吧为例)获得你喜欢的照片下载到本地电脑上——Jason niu

    import urllib.requestimport re import os def open_url(url): req=urllib.request.Request(url) req.add_ ...