JS 函数式编程思维简述(二):高阶函数

栏目: JavaScript · 发布时间: 5年前

内容简介:高阶函数(High-Order Function)是函数式编程思维中的重要条件,而满足该条件的编程语言则需要将函数作为该语言的将函数视作一等公民的语言有:JavaScript、Golang、Python、Scala、Lua、Lisp、Scheme等。同时,有着越来越多的其他语言看上了函数式编程的出彩之处,以其特有的方式实现着符合自身编程方式的在
  1. 简述
  2. 无副作用(No Side Effects)
  3. 高阶函数(High-Order Function)
  4. 科里化(Currying)
  5. 闭包(Closure)
  6. 不可变(Immutable)
  7. 惰性计算(Lazy Evaluation)
  8. Monad

一等公民

高阶函数(High-Order Function)是函数式编程思维中的重要条件,而满足该条件的编程语言则需要将函数作为该语言的 一等公民 来看待。符合 一等公民 的条件是:

  • 函数可以作为一种数据类型的值,赋值于一个变量;
  • 函数可以作为参数,在其他函数中进行传递;
  • 函数可以作为返回值,在其他函数中返回;
JS 函数式编程思维简述(二):高阶函数

image

将函数视作一等公民的语言有:JavaScript、Golang、 Python 、Scala、 Lua 、Lisp、Scheme等。同时,有着越来越多的其他语言看上了函数式编程的出彩之处,以其特有的方式实现着符合自身编程方式的 高阶函数

函数类型

JavaScript 中,函数是数据类型 object 的子类型——即是指一种对象类型。我们可以通过 typeof 操作符检测一个值是否是一个函数类型:

// 一个函数声明
function foo(x){
    return x + 10;
}
typeof foo; // 返回值:'function'

然而,实际上在 JavaScript 中,函数并非是 基本的数据类型 ,函数隶属于对象类型。能够使用 typeof 操作符进行检测仅仅是语言提供的便利:

// 声明一个 number 类型的变量
const n = 13;
// 一个函数声明
function foo(x){
    return x + 10;
}
typeof foo; // 结果:'function'
typeof n; // 结果:'number'

// 检测 n 所持有的值是否是对象
n instanceof Object; // 结果:false

// 检测 foo 所持有的值是否是对象
foo instanceof Function; // 结果:true
Function instanceof Object; // 结果:true
foo instanceof Object; // 结果:true

可见,函数是一个隶属于 Function 的对象,而 Function 本身又隶属于顶层 Object ,是它的子对象。因此,一个函数的实例,也隶属于 Object ,他们之间拥有间接的继承关系。

很多有 面向对象 经验的同学可能会想,实例化对象不是通过 new 关键字调用类的构造函数来进行的吗?这个问题很简单:拿 Java 例举, Java 中拥有字面量形式的对象声明方式 String str = "I like Java!"; ,声明变量 str 的过程中实际上也构建了一个字符串对象,并没有显式的使用关键字 new

JavaScript 中,以字面量的方式构建对象有很多种,比如:

// 数组字面量
const arr = [1, 2, 3];
// 对象字面量
const obj = {id : 'xx001'};
// 函数字面量
function foo(){}            // 函数声明
const bar = function(){}    // 函数表达式
const baz = (x) => x + 3;   // ES6提供的lambda表达式函数

函数入参

由于函数也是一个对象,因此函数也可以作为其他函数的参数,作为入参:

// 一个函数声明
const add2 = (x) => x + 2;          // 参数x基础上加2的函数
const sub2 = (x) => x - 2;          // 参数x基础上减2的函数
const result = (y, f) => y * f(y);  // 参数y基础上乘以 函数参数f 的运算结果

result(4, add2);    // 结果: 24
result(4, sub2);    // 结果: 8

JavaScript 内置对象中,也有非常多的函数入参实例,比如 Array.prototype.map 函数的简单实现:

// 一个高仿的 Array.prototype.map 函数
const map = function(arr, f){
    const t = []; 
    for(let i=0;i<arr.length; t.push(f(arr[i],i++,arr)));
    return t;
}
// 声明一个数组
const a1 = [1,2,3,4];
// map函数调用:参数 f 所示为每一个值乘以3,并且返回一个新数组
const a2 = map(a1, (e) => e*3); // 结果:[3, 6, 9, 12]

函数返回值

函数可以作为参数,当然也可以作为返回值。作为返回值的函数,常用于缓存上一个函数的执行状态:

// 一个函数声明
const add2 = (x) => x + 2;          // 参数x基础上加 2 的函数
const mul2 = (x) => x * 2;          // 参数x基础上乘以 2 的函数

// 该函数用于计算,计算结果不会直接得出,而是缓存了用于计算的两个函数
const calc = function(f1, f2){
    return (y) => f1( f2(y) );
}

// 根据缓存顺序不同,生成的新的函数执行过程也不同
const c01 = calc(add2, mul2); 
c01(3); // 结果: 8

const c02 = calc(mul2, add2); 
c02(3); // 结果:10

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java编程思想

Java编程思想

埃克尔 / 机械工业出版社 / 2007-5-1 / 79.00元

《Java编程思想(英文版•第4版)》内容简介:特色:1.适合初学者与专业人员的经典的面向对象的叙述方式;为更新的Java SE5/6的相关内容增加了新的示例和章节。2.测验框架显示程序输出。3.设计模式贯穿于众多示例中:适配器、桥接器、职责链、命令、装饰器、外观、工厂方法、享元、点名、数据传输对象、空对象、代理、单例、状态、策略、模板方法以及访问者。4.为数据传输引入了XML;为用户界面引入了S......一起来看看 《Java编程思想》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具