Skip to content

Latest commit

 

History

History
104 lines (70 loc) · 2.27 KB

2016-12-13-js.md

File metadata and controls

104 lines (70 loc) · 2.27 KB

JS 查漏 - 函数式编程

纯函数

特点

  • 相同输入总是有相同输出

    • 可缓存
  • 无副作用,诸如触发事件,是设备输入输出或是改变外部变量等

    • Object.freeze(obj)
    • Object.assign(target, source)
  • 不依赖外部变量

好处

  • 可移植性/自文档化
  • 可测试性
  • 合理性,引用透明,可等式推导
  • 并行代码

函数式编程

函数式一等公民,与其他数据类型地位相等

柯里化

只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。

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

add(1)(2) // return 3

库:loadsh、ramda

代码组合

类似管道处理,符合结合律

var compose = function(f,g) {
  return function(x) {
    return f(g(x));
  };
};

pointfree 模式

不需要参数构造的函数

var snakeCase = compose(replace(/\s+/ig, '_'), toLowerCase);
// use this to debug
var trace = curry(function(tag, x){
  console.log(tag, x);
  return x;
});

尾调用

指一个函数里的最后一个动作是一个函数调用的情形 如果这个函数在尾位置调用本身,则为称为尾递归

尾调用优化

当一个普通函数内部调用函数,会造成不断压栈。比如 A 函数内部调用 B 函数,此时将在 A 调用信息(保存 A 函数调用所需的局部变量、调用位置等)之上形成一个 B 调用信息,如果 B 函数内部又调用了 C 函数,那么 C 的调用信息又会被压栈。以此类推,直到有函数返回,则调用信息依次反向出栈。

尾调用因为函数最后的返回结果是另一个函数,而不需要保留其他的调用信息。所以,只需用返回函数的调用记录代替外层函数即可,可使调用记录保持只有一项,大大节省了栈空间。

//优化前
const factorial = n => {
  return [1][n - 1] ? 1 : n * factorial(n - 1);
}
// 优化后
const factorial = (n, total = 1) => {
    return [1][n - 1] ? total : factorial(n - 1, total * n);
}

支持

ES6 严格模式下支持尾递归优化

参考

1483 days left