zoukankan      html  css  js  c++  java
  • 高阶函数简述 js

    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>
  • 相关阅读:
    WPS设置去广告
    Android,几款apk工具
    Eclipse 使用
    linux su和sudo命令的区别
    CentOS下安装SecureCRT的sz/rz工具包
    CentOS下安装SecureCRT的sz/rz工具包
    CentOS下安装SecureCRT的sz/rz工具包
    VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
    修改CentOS系统的默认启动级别
    修改CentOS系统的默认启动级别
  • 原文地址:https://www.cnblogs.com/mengfangui/p/9812654.html
Copyright © 2011-2022 走看看