前端函数式攻城指南

杨旭 bio photo By 杨旭

前端函数式攻城指南

JavaScript是函数式语言么?

JavaScript 本质上是基于原型的多范式编程语言,在JavaScript中函数是一等公民,所以它也支持函数式编程。

函数是一等公民:函数是变量的语言。函数能成为实参,能作为返回值。 包含函数作为参数或者返回值的函数,叫做高阶函数

编程范式

常见的编程范式包括:命令式、函数式、面向对象、逻辑式

  • 命令式 - 面向过程的编程模式,一条条指令顺序执行。
  • 函数式 - 更接近于数学,简单来说就是对表达式求值;抽象方式是抽象成带有动作的函数
  • 面向对象 - 接近于现实世界,封装好的对象之间通过消息互相传递信息
  • 逻辑式 - 通过提问找到答案的编程方式

JavaScript的函数式支持

函数是一等公民。

作为参数:例如map函数,将核心逻辑封装在匿名函数中

作为返回值:按照不同的使用场景拥有不同的名称

  • 柯里化:把一个多参的函数变成一次只能接受一个参数的函数的过程。部分的配置函数,并且继续使用配置过的函数
  • trunk:不被立即执行的函数,等待合适的时候被人调用

越来越函数式的ES6

  • Babel、Traceur编译器将ES6翻译为多浏览器兼容的版本
  • 借鉴于CoffeeScript的箭头函数,带来简洁、清晰的语法;绑定this的词法作用域,避免 var self = this 的尴尬;
  • 尾递归优化:除浏览器的支持外,Babel在编译过程中就执行了尾递归优化
  • Destructor:按照模式匹配到变量,例如:[top, …middleAndButtom] = [‘top’, ‘middle’, ‘bottom’]

作为函数式编程语言,JavaScript还缺少什么

JavaScript的原型链主要是支持面向对象编程,同时也支持一等函数。

但是在语言层面对于函数式的支持还是十分局限的,需要很多第三方库的支持。

不可变数据结构

  • 任何操作都不应该改变对象的内部结构
  • JavaScript中除了6中原始类型,其余都是可变的。

惰性求值

  • 求值过程并不是立即发生的,在计算过程中,一些表达式是可以消除的
  • JavaScript中,及时表达式没有用到,也是会执行

    函数组合

  • 函数式编程的抽象方式于面向过程相反,前者抽象为“动词”,后者抽象为“名词”
  • 面向对象通过组合对象产生新功能,函数式通过组合函数形成新的函数
  • JavaScript没有一个原生的利于组合函数的方式

    尾递归优化

  • 关键是解释器识别尾递归
  • 可以在递归过程中不失去性能优势

  • Underscore API不复合常见的函数式语法
  • Mori 使用ClojureScript的数据结构,根本上消除了JavaScript可变的数据结构模型
  • Facebook维护的Immutable.js
  • 轻量级的lodash