`

js 高阶函数

    博客分类:
  • js
 
阅读更多

参考:js高阶函数

 

JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

一个最简单的高阶函数:

function add(x, y, f) {
    return f(x) + f(y);
}

当我们调用add(-5, 6, Math.abs)时,参数xyf分别接收-56和函数Math.abs,根据函数定义,我们可以推导计算过程为:

x = -5;
y = 6;
f = Math.abs;
f(x) + f(y) ==> Math.abs(-5) + Math.abs(6) ==> 11;
return 11;

map

 

由于map()方法定义在JavaScript的Array中,我们调用Arraymap()方法,传入我们自己的函数,就得到了一个新的Array作为结果:

'use strict';

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

再看reduce的用法。Array的reduce()把一个函数作用在这个Array[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,其效果就是:

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

比方说对一个Array求和,就可以用reduce实现:

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

 

 

练习:利用reduce()求积:

 return arr.reduce(function (x, y) {return x * y;}); 

 

 

 

练习:不要使用JavaScript内置的parseInt()函数,利用map和reduce操作实现一个string2int()函数:

return s.split("").map(function(x){return x-0}).reduce(function (x, y){return x*10 + y});

 

 

 

练习:请把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入: ['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']

function up(x){ return x[0].toUpperCase()+x.substring(1).toLowerCase(); } return arr.map(up);

 

小明希望利用map()把字符串变成整数,他写的代码很简洁:

'use strict';

var arr = ['1', '2', '3'];
var r;
r = arr.map(parseInt);
console.log(r);

结果竟然是1, NaN, NaN,小明百思不得其解,请帮他找到原因并修正代码。

 

 

由于map()接收的回调函数可以有3个参数:callback(currentValue, index, array),通常我们仅需要第一个参数,而忽略了传入的后面两个参数。不幸的是,parseInt(string, radix)没有忽略第二个参数,导致实际执行的函数分别是:

  • parseInt('0', 0); // 0, 按十进制转换

  • parseInt('1', 1); // NaN, 没有一进制

  • parseInt('2', 2); // NaN, 按二进制转换不允许出现2

可以改为r = arr.map(Number);,因为Number(value)函数仅接收一个参数。

filter

filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。

map()类似,Arrayfilter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。

例如,在一个Array中,删掉偶数,只保留奇数,可以这么写:

var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
    return x % 2 !== 0;
});
r; // [1, 5, 9, 15]

把一个Array中的空字符串删掉,可以这么写:

var arr = ['A', '', 'B', null, undefined, 'C', '  '];
var r = arr.filter(function (s) {
    return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
});
r; // ['A', 'B', 'C']

可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。

回调函数

filter()接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:

var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
    console.log(element); // 依次打印'A', 'B', 'C'
    console.log(index); // 依次打印0, 1, 2
    console.log(self); // self就是变量arr
    return true;
});

利用filter,可以巧妙地去除Array的重复元素:

'use strict';

    var r,arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
    r = arr.filter(function (element, index, self) {
        console.log(self.indexOf(element)+'-----'+index);
        return self.indexOf(element) === index;
    });
    console.log(r.toString());

去除重复元素依靠的是indexOf总是返回第一个元素的位置,后续的重复元素位置与indexOf返回的位置不相等,因此被filter滤掉了。

练习

请尝试用filter()筛选出素数:

var r = arr.filter(function(element){ if (element === 1) { return false;} for (var i=2; i<=element/2;i++){ if (element%i === 0){ return false; } } return true; }); return r;

 

sort

排序算法

排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个对象呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。通常规定,对于两个元素xy,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。

JavaScript的Arraysort()方法就是用于排序的,但是排序结果可能让你大吃一惊:

// 看上去正常的结果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];

// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']

// 无法理解的结果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]

第二个排序把apple排在了最后,是因为字符串根据ASCII码进行排序,而小写字母a的ASCII码在大写字母之后。

第三个排序结果是什么鬼?简单的数字排序都能错?

这是因为Arraysort()方法默认把所有元素先转换为String再排序,结果'10'排在了'2'的前面,因为字符'1'比字符'2'的ASCII码小。

 

如果不知道sort()方法的默认排序规则,直接对数字排序,绝对栽进坑里!

幸运的是,sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。

要按数字大小排序,我们可以这么写:

'use strict';

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]

如果要倒序排序,我们可以把大的数放前面:

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

默认情况下,对字符串排序,是按照ASCII的大小比较的,现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以:

var arr = ['Google', 'apple', 'Microsoft'];
arr.sort(function (s1, s2) {
    x1 = s1.toUpperCase();
    x2 = s2.toUpperCase();
    if (x1 < x2) {
        return -1;
    }
    if (x1 > x2) {
        return 1;
    }
    return 0;
}); // ['apple', 'Google', 'Microsoft']

忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。

从上述例子可以看出,高阶函数的抽象能力是非常强大的,而且,核心代码可以保持得非常简洁。

最后友情提示,sort()方法会直接对Array进行修改,它返回的结果仍是当前Array

var a1 = ['B', 'A', 'C'];
var a2 = a1.sort();
a1; // ['A', 'B', 'C']
a2; // ['A', 'B', 'C']
a1 === a2; // true, a1和a2是同一对象

 

分享到:
评论

相关推荐

    java模拟js高阶函数

    Java 模拟 JavaScript 的高阶函数是编程领域中一个有趣且实用的主题,它涉及到语言间的特性差异和跨语言编程的概念。在JavaScript中,高阶函数是指可以接受其他函数作为参数或者返回函数作为结果的函数。这在处理回...

    vue写法-使用js高阶函数实现多条件搜索功能

    之前出过一个react写法的前端搜索([react写法——使用js高阶函数实现多条件搜索功能] 今天我们再研究一下vue中怎么实现。 react和vue有什么区别? 这个区别要细说可太多了,但是最终都能归为语法不同,封装方式不同...

    详解JavaScript 高阶函数

    JavaScript 高阶函数详解 JavaScript 高阶函数是函数式编程中的一种特殊函数,通过将函数作为参数传入另一个函数,或者将函数作为另一个函数的返回值返回,高阶函数可以抽象我们的代码,将我们的命令式编程转换为...

    JAVASCRIPT函数之高阶函数.pdf

    在本篇关于JavaScript高阶函数的文档中,我们将会详细探讨JavaScript中的高阶函数概念及其在实际编程中的应用。高阶函数是函数式编程的核心概念之一,在JavaScript中尤为重要,因为JavaScript函数是"一等公民"。 ##...

    Javascript 高阶函数使用介绍

    在了解JavaScript高阶函数使用之前,首先需要明确什么是高阶函数。在编程中,高阶函数被定义为那些接受函数作为参数或返回函数作为结果的函数。在JavaScript这种弱类型语言中,函数既不对输入的参数类型进行严格定义...

    JavaScript高阶函数_动力节点Java学院整理

    JavaScript高阶函数是JavaScript编程中一个非常重要的概念,它在函数式编程中占据了核心地位。高阶函数(Higher-Order Function)是指能够接受一个或多个函数作为参数,并且可能返回一个新的函数的函数。这种特性...

    JAVASCRIPT函数之高阶函数[文].pdf

    JavaScript中的高阶函数是函数式编程的一个核心特性,它允许函数作为其他函数的参数或返回结果。这种灵活性使得JavaScript能够处理更加复杂的编程任务,尤其是在处理数据操作和异步操作时。接下来,我们将深入探讨高...

    高阶函数-函数柯里化- 手写

    一、高阶函数 定义:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数: 1、若 A 函数,接受的参数是一个函数,那么 A 就可以称为高阶函数。 2、若 A 函数,调用的返回值依然是一个函数,那么 A 就...

    JS高阶函数原理与用法实例分析

    总的来说,JS高阶函数提供了强大的工具,使得我们能够编写更加灵活、可复用和模块化的代码。掌握高阶函数的原理和用法对于提升JavaScript编程技巧至关重要。无论是使用内置的数组方法还是自定义高阶函数,它们都能...

    Javascript中的高阶函数介绍

    在Javascript编程中,高阶函数(Higher-order function)是一类特殊的函数,它们对其他函数进行操作。具体来说,高阶函数可以接受一个或多个函数作为参数,也可以将函数作为其返回值。这类函数概念在很多现代编程...

    Javascript 是你的高阶函数(高级应用)

    JavaScript中的高阶函数是其灵活性和强大的功能之一,它允许函数作为其他函数的参数或返回结果。这样的特性使得代码更加模块化,提高了代码的重用性和可读性。以下是几个高阶函数的应用场景: 1. **回调函数**: ...

    关于JavaScript中高阶函数的魅力详解

    JavaScript 的高阶函数跟 Swift 的高阶函数类似 常见的高阶函数有: Map、Reduce、Filter、Sort 高阶函数是指至少满足下列条件之一的函数  1:函数可以作为参数被传递  2:函数可以作为返回值输出 JavaScript语言...

    前端进阶函数科利华,高阶函数

    JavaScript 语言中内置了一些高阶函数,比如 Array.prototype.map、Array.prototype.filter 和 Array.prototype.reduce,它们接受一个函数作为参数,并应用这个函数到列表的每一个元素。 Array.prototype.map() ...

    深入学习JavaScript 高阶函数

    JavaScript中的高阶函数是编程中的一个核心概念,它在函数式编程中占据着重要的地位。高阶函数的主要特点是能够处理函数作为输入参数或者输出结果,这使得代码更加灵活且易于复用。在JavaScript中,由于函数本身被视...

    深入解析 JavaScript 中的高阶函数与函数式编程技巧

    内容概要:本文详细介绍了 JavaScript 中几种重要的高阶函数及其应用方式,其中包括通过 rest 参数传递任意参数(addArrayElements 函数)、数组映射转换(arrToString 方法)、闭包用于封装状态计数器(makeCounter...

    react写法-使用js高阶函数实现多条件搜索功能

    用react写法来实现,思路+步骤: 第一步:准备数据 首先,需要创建一段假数据,模拟后端接口返回的数据。 第二步:根据数据结构渲染Dom 这一步,我们要根据数据接口,看看要设计几个搜索框。 根据第一步我们设计的...

Global site tag (gtag.js) - Google Analytics