JS高阶函数

1.高阶函数:就是一个函数的参数是函数,或者返回值是函数,满足其中一个就是高阶函数。

开闭原则:对扩展是开发的,对修改是封闭的。

    //定义一个计算器函数

    // 注意:callback参数,接收的是一个函数。

    function calc(num1,num2,callback){

                return callback(num1,num2)

    }

    //简写

    //let calc=(num1,num2,callback)=>callback(num1,num2);

    // 定义一个加法运算

    let add = function(num1,num2){

                return num1 + num2

    }

    // 计算两个数,统一调用calc方法,具体是如何计算,通过回调函数去实现。

    //先定义一个回调函数,在传进来

    let r1 = calc(300,100,add)

    console.log(r1);

    //回调函数可以直接调用时定义

    let r2 = calc(300,100,function(num1,num2){return num1 - num2})

    console.log(r2);

    //通常情况下,回调函数都会写成箭头函数的形式

    let r3 = calc(300,100, (num1,num2)=>num1 * num2)

    console.log(r3);

    let r4 = calc(300,100,(num1,num2)=>num1/num2)

    console.log(r4);

    let r5 = calc(16,6,(num1,num2)=>num1%num2)

    console.log(r5);

2.回调函数练习

    let arr = [11, 22, 33, 44, 55, 66, 77, 88, 99, 111, 222, 333, 444]

    //定义一个kaiFor函数,这个函数需要传两个参数:数组,回调函数

    function kaifor(arr, callback) {

    //循环数组

            for (let i = 0; i < arr.length; i++) {

    //调用回调函数callback,将数组中的每个数传进去,返回true,表示满足条件

                    if (callback(arr[i])) {

                            console.log(arr[i]);

                    }

            }

    }

    // 业务一:循环输出数组中所有的奇数

    // 定义一个函数,用于返回一个数是不是奇数

    function isJs(num){

            return num%2!==0

    }

    kaifor(arr,isJs)

    console.log('--------------------');

    // 业务二:循环输出数组中所有的偶数

    kaifor(arr,function(num){return num%2===0})

    console.log('--------------------');

    // 业务三:循环输出数组中所有的能被3整除的数

    kaifor(arr,num => num%3===0)

    console.log('--------------------');

    // 业务四:循环输出数组中所有的3位数

    kaifor(arr,num => num>=100 && num<1000)

3.数组的高阶方法

    let arr = [11, 22, 33, 44, 55, 66, 77, 88, 99, 111, 222, 333, 444]

1.forEach()方法,用于循环遍历整个数组

    //该方法的参数是一个回调函数,回调函数可传两个参数,第一个参数是数组中的每一项元素

    //第二个参数是每一项元素对应的下标。

    //注意:第二个参数可以省略。

    arr.forEach((val,index)=>console.log(index+'-'+val))

2.filter()方法,用于过滤数组中的元素,返回过滤结果

    let arr1 = arr.filter(val=>val%2==0)

    console.log(arr1);

    let arr2 = arr.filter(val=>val%3==0)

    console.log(arr2);

3.find()方法,用于获取数组中满足规则的第一个元素

    let num1 = arr.find(val=>val%3==0)

    console.log(num1);

4.findIndex()方法,用于获取数组中满足规则的第一个元素下标

    let index1 = arr.findIndex(val=>val%3==0)

    console.log(index1);

5.some()方法,用于表示数组中是否有满足指定规则的元素,有返回true,一个都没有返回false

    let isHave1 = arr.some(val=>val>1000)

    console.log(isHave1);

    let isHave2 = arr.some(val=>val==222)

    console.log(isHave2);

6.every()方法,用于表示数组中是否所有元素都满足指定的规则

    let isHave3 = arr.every(val=>val>10)

    console.log(isHave3);

    let isHave4 = arr.every(val=>val%2==0)

    console.log(isHave4);

7.map()方法,用于将原始数组里面的数据根据指定的规则返回新的数组

    let arr3  = arr.map(r=>r%7)

    console.log(arr3);

    console.log('------------------------------');

    let arr4 = [33,22,55,7,46]

8.sort()方法,对数组的元素进行排序

    回调函数需要传两个参数,返回参数1-参数2是升序,返回参数2-参数1是降序

    console.log(arr4);

    arr4.sort((a,b)=>a-b)

    console.log(arr4);

    arr4.sort((a,b)=>b-a)

    console.log(arr4);

9.reduce()方法,统计数组中元素的和(从左到右)

    a是数组中的一个数,b从数组中第二个数开始,回调函数的返回是a的下一次的值

    let sum1 = arr4.reduce((a,b)=>{

            return a+b

    })

    console.log(sum1);

    console.log('-------------------------------');

    // reduce()方法,可以给a设置一个起始值,这里的100就是a的起始值,b从数组的第一位       (下标是0)开始

    let sum2 = arr4.reduce((a,b)=>{

            return a+b

    },100)

    console.log(sum2);

10.reduceRight()方法,统计数组中元素的值(从右到左)

    let sum3 = arr4.reduceRight((a,b)=>{

            return a+b

    })

    console.log(sum3);

4.手写实现数组的高阶方法

        let arrs = [11, 22, 33, 44, 55]

    1.手写forEach()方法

        function forEach(arr, callback) {

            for (let i = 0; i < arr.length; i++) {

                callback(arr[i], i)

            }

        }

        forEach(arrs, (item, index) => console.log(index + '---' + item))

        console.log('----------------------------');

    2.手写filter()方法

        function filter(arr, callback) {

            let val = [];

            for (let i = 0; i < arr.length; i++) {

                if (callback(arr[i])) {

                    val.push(arr[i]);

                }

            }

            return val;

        }

        console.log(filter(arrs, num => num % 2 == 0));

        console.log(filter(arrs, num => num > 30));

        console.log('----------------------------');

    3.手写find()方法

        function find(arr, callback) {

            for (let i = 0; i < arr.length; i++) {

                if (callback(arr[i])) {

                    return arr[i];

                }

            }

        }

        console.log(find(arrs, num => num % 2 == 0));

        console.log(find(arrs, num => num > 30));

        console.log('----------------------------');

    4.手写findIndex()方法

        function findIndex(arr, callback) {

            for (let i = 0; i < arr.length; i++) {

                if (callback(arr[i])) {

                    return i;

                }

            }

        }

        console.log(findIndex(arrs, num => num % 2 == 0));

        console.log(findIndex(arrs, num => num > 30));

        console.log('----------------------------');

    5.手写some()方法

        function some(arr, callback) {

            for (let i = 0; i < arr.length; i++) {

                if (callback(arr[i])) {

                    return true;

                }

            }

            return false;

        }

        console.log(some(arrs, num => num % 2 == 0));

        console.log(some(arrs, num => num > 100));

        console.log('---------------------------');

    6.手写every()方法

        function every(arr, callback) {

            for (let i = 0; i < arr.length; i++) {

                if (!callback(arr[i])) {

                    return false;

                }

            }

            return true;

        }

        console.log(every(arrs, num => num > 10));

        console.log(every(arrs, num => num % 3 == 0));

        console.log('---------------------------');

    7.手写map()方法

        function map(arr, callback) {

            let val = [];

            for (let i = 0; i < arr.length; i++) {

                val.push(callback(arr[i]));

            }

            return val;

        }

        console.log(map(arrs, num => num % 3));

        console.log(map(arrs, num => num / 2));

        console.log('----------------------------');

    8.手写sort()方法

        function sort(arr, callback) {

            for (let i = 0; i < arr.length - 1; i++) {

                for (let j = i + 1; j < arr.length; j++) {

                    if (callback(arr[i], arr[j]) > 0) {

                        let temp = arr[i]

                        arr[i] = arr[j]

                        arr[j] = temp;

                    }

                }

            }

            return arr;

        }

        console.log(sort(arrs, (a, b) => a - b));   //升序

        console.log(sort(arrs, (a, b) => b - a));   //降序

        console.log('----------------------------');

    9.手写reduce()方法

        function reduce(arr, callback, initNum) {

            for (let i = 0; i < arr.length; i++) {

                let r = callback(initNum, arr[i])

                initNum = r  //每次返回的结果,需要替换initNum

            }

            return initNum;

        }

        console.log(reduce(arrs, (a, b) => a + b, 0));

        console.log('----------------------------');

    10.手写reduceRight()方法

        function reduceRight(arr, callback, initNum) {

            for (let i = arr.length - 1; i >= 0; i--) {

                let r = callback(initNum, arr[i])

                initNum = r  //每次返回的结果,需要替换initNum

            }

            return initNum

        }

        console.log(reduceRight(arrs, (a, b) => a + b, 0));

5.闭包函数

    function a(){

            console.log('a函数被调用了...');

            let num1 = 100

            let num2 = 200

            function b(){

                console.log('b函数被调用了...');

                console.log(num1 + num2);

            }

            //返回的返回值也是一个函数,那么a函数,就是高阶函数。

            return b

    }

        // 通常情况下,函数执行完成后,函数里面定义的变量,会被销毁。

        // a函数,已经调用完毕了,但是a函数里面定义变量,始终在内存中,因为b函数中用到了a函数中定义的变量。

        // 那么此时这两个函数,就称之为:闭包函数。

    let c = a()

    c()

    console.log('------------------------------------------');

    // 闭包函数的实际案例

    function calc(num1,num2,type){

            switch(type){

                case '+':

                    console.lo2g(`${num1}+${num72}=${num1+num2}`);

                    break;

                case '-':

                    console.log(`${num1}-${num2}=${num1-num2}`);

                    break;

            }

    }

    // 在实际开发中,我们在做num1和num2的计算之前,可能需要先做其他事情

    let num1 = 100

    let num2 = 50

    // 在做其他事情的过程中,我们的数据很有可能会被篡改。

    console.log('查看用户是否登录');

    num1 = 555

    num2 = 145

    console.log('检查用户的权限');

    calc(num1,num2,'+')   //运行结果不对,因为变量的值被篡改了。

    console.log('------------------------------------------');

    // 定义一个闭包函数,实现计算器功能

    function myCalc(num1,num2,type){

            switch(type){

                case '+':

                    return function(){

                        return num1 + num2

                    }

                case '-':

                    return function(){

                        return num1 - num2

                    }

            }

    }

    //先准备好你的数据

    let n1 = 100

    let n2 = 50

    //将你的数据传给计算器方法,由计算器方法,返回一个计算方法。

    let js = myCalc(n1,n2,'+')

    //在做具体的计算之前,还先做些其他的事情

    console.log('查看用户是否登录');

    n1 = 555

    n2 = 145

    console.log('检查用户的权限');

    //其他事件准备好了后,执行计算方法

    console.log(js());

6.arguments

    function fn1(a,b,c){

            //方法在调用时,如果没有传递实参,形参的值是undefined

            console.log(a,b,c);

            // arguments是函数内部的一个内置对象

            // arguments对象里面保存这方法的所有参数

            // arguments对象里面有个一个callee方法,该方法指向当前方法本身

            console.log(arguments);

            let sum = 0;

            for(let i=0;i<arguments.length;i++){

                sum+=arguments[i]

            }

            return sum;

    }

    let sum = fn1(100,200,300,400,500,600)

    console.log(sum);

    // 计算1-20之间所有数的求和

    function calc(num){

            if(num===1){

                return num

            }

            // arguments.callee指向当前方法本身。

            // 所以,在写递归算法时会经常使用。

            return num + arguments.callee(num-1)

    }

    console.log(calc(20));

7.分页方法

    // 定义一个数组

    let arr = [11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999]

    // 每页3条数据,返回第3页数据

    let r1 = arr.slice(6,9)

    console.log(r1);

    // 每页4条数据,返回第4页数据

    let r2 = arr.slice(12,16)

    console.log(r2);

    // 没有5条数据,返回第3页数据

    let r3 = arr.slice(10,15)

    console.log(r3);

    console.log('------------------------------');

    //定义一个分页方法,方法的三个参数分别是:原始数组,页码,每页数量

    function pageDate(arr,pageIndex,pageSize){

            let start = (pageIndex-1)*pageSize

            let end = start+pageSize

            //根据起始下标和结束下标,从原始数组中截取对应的数据并返回

            return arr.slice(start,end)

    }

    console.log(pageDate(arr,3,3));

    console.log(pageDate(arr,4,4));

    console.log(pageDate(arr,3,5));

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容