打赏

高阶函数简述 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>

 

posted @ 2018-10-18 19:29  孟繁贵  阅读(188)  评论(0编辑  收藏  举报
TOP