函数式特征
-
Functions as first-class values, 函数作为一等公民.
可以把函数作为参数传递, 从而构造出 高阶函数 各种用法.
const hi = function(name){
return "Hi " + name;
};
const greeting = function(name) {
return hi(name);
};
const greeting = hi
一个函数被不必要地包裹起来了,而且发生了改动,那么包裹它的那个函数也要做相应的变更.
httpRequest('/post/method', function(json, err){
return renderPost(json, err);
});
httpRequest('/post/method', renderPost);
目的: 规定代码粒度, 精简代码逻辑, 提高可维护, 可读性.
-
Pure functions, 纯函数.
纯函数: 相同的输入永远得到相同的输出, 没有任何可观察到的副作用.
副作用: 与外部环境任何相关的.
目的: 保证写出的函数不会无故出现不可预知的错误,确保函数这个粒度的代码的准确性,稳定性.
slice
, splice
-
Referential transparency, 引用透明.
-
Controlled effects, 受控的副作用, 主要手段是隔离.
redux中的action函数
// 不纯的 const signUp = attrs => { welcomeUser(saveUser(attrs)) } // 纯的 const signUp = (Db, Email, attrs) => () => { welcomeUser(Email, saveUser(Db, attrs)); };
-
Everything is an expression, 一切皆是表达式.
JavaScript 代码体现为, 全为声明赋值语句. 避免涉及到跳转循环等语句. 需要辅助使用Maybe、尾递归等来优化流程.
-
No loops, 换句话说, 不能用 for/while, 因为这两个写法当中的
i++
依赖可变数据.JavaScript 经常使用 for/while. 目前的浏览器尚未很好的支持尾递归.
-
Immutable values. 不可变数据
JavaScript 默认可变, 仅有的手段用
Object.freeze
可以强行锁定对象或者 const 锁定变量本身, 另外就是 immutable-js 那样的共享结构的不可变数据作为类库来实现. -
Algebraic Datatypes, 代数类型系统.
JavaScript 没有静态类型系统.
-
Product types.
-
No Null. 无空对象
JavaScript 当中有 undefined 和 null. 用 Maybe Monad 这样的概念, 通过类型系统进行了抽象和限制.
-
A function always returns a value, 函数永远都有返回值.
-
A function takes exactly one value, 函数只接收一个参数。
多参函数通过tuple来模拟。
-
Currying, 柯理化.
JavaScript 种可以广泛应用函数的这个概念: 只传递部分参数调用函数,返回一个新函数处理剩余的参数. (仍然是一个输入对应一个输出)
多箭头函数.
辅助函数库提供. lodash提供.
(x) => (y) => (z) => x + y + z (x, y, z) => x + y + z
非常方便于使用多参数函数创建实用的新函数. 逆推过去, 其实它的意思是,将函数按照每处理一段与特定一个或者多个(鼓励为一个)参数相关的一段逻辑作为一个函数来处理.
Javascript中有种常见用法叫partial application
-
Lexical scoping, 词法作用域.
-
Closures, 闭包.
-
Pattern matching, 模式匹配.
类似解构赋值之类.
-
Lack of subtyping。无子类型概念,没有通俗的’OO’概念.
-
Safety, 安全性.
-
Type Safety, 类型安全
-
No Globals, 无全局变量。
-
α-conversion α转换
alpha转换是参数重命名操作,意思是函数变量名不影响函数含义.
-
β-reduction beta规约
-
η-conversion
eta转化的意思是如果两个函数对于所有相同的传入的参数都能得到一样的结果,则两个函数相等。
-
Substitution as a principle 替换原则
-
Lazy evaluation, 惰性计算.
语言级特性. JavaScript 是严格求值的, 不支持惰性计算. 惰性计算就是说代码里的表达式被真正使用来才会真正执行, 否则就像是个 thunk, 继续以表达式存储着.
函数
-
高阶函数
凡有参数或者返回值为函数, 被称为高阶函数.
-
combinator组合子
compose函数: B combinator
// compose函数的最简单实现
const compose = (a, b) => c => a(b(c))
// sample
const cookAndEat = (food) => eat(cook(food));
// 等同
const cookAndEat = compose(eat, cook);
compose函数的复杂实现参考redux库/lodash库/ramda库的实现.
K combinator
const K = x => y => x;
这是一个最基本的高阶函数
I combinator
const I = x => x;
-
函数装饰器
not函数装饰器实现
const not = fn => x => !fn(x)
// sample
const something = x => x != null
const nothing = x => !something(x)
// 正经的写法
const nothing = not(something)
once函数装饰器
maybe函数装饰器
部分调用函数装饰器
const callLeft = (fn, ...args) => (...remainArgs) => fn(...args, ...remainArgs)
const callRight = (fn, ...args) => (...remainArgs) => fn(...remainArgs, ...args)
unary函数装饰器
// 将参数装饰为只处理一个参数的函数
const unary = fn => fn.length === 1
debounce函数和throttle函数