600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > JavaScript 函数式编程思想

JavaScript 函数式编程思想

时间:2024-05-06 11:43:58

相关推荐

JavaScript 函数式编程思想

来自 Professor Frisby’s Mostly Adequate Guide to Functional Programming

英文版本

中文版本-版本较老

函数式编程是一种编程范式, 所谓范式, 就是一种编程规范

面向对象: 将现实世界的事物抽象为类与对象, 通过封装, 继承, 多态来表示事物之间的联系函数式: 将现实世界事物与事物之间的联系抽象到程序中

这里的函数指的是映射形如 y=x2y = x^2y=x2

代码优化

思考: 一个函数, 参数在另一个函数中调用 是否可以直接将另一个函数拿过来?

形如以下函数

args => actualCallFunction(args)❗️ 只会徒增代码量 这种形式等价于actualCallFunction

const log = arg => console.log(arg)const a = arg => log(arg)// a 和以下代码等价const b = loga(123)// 123b(456)// 456

再看个 🌰

const actualCallFunction = _ => console.log('qweasdzxc')const foo = aFunction => actualCallFunction(arg => aFunction(arg))// 优化一下const foo2 = aFunction => actualCallFunction(aFunction)// 接着优化const foo3 = actualCallFunctionfoo()// qweasdzxcfoo2()// qweasdzxcfoo3()// qweasdzxc

一些概念

纯函数: 相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用

副作用中的“副”是滋生 bug 的温床

副作用可能包含,但不限于:

更改文件系统往数据库插入记录发送一个 http 请求可变数据打印/log获取用户输入DOM 查询访问系统状态

curry:只需传给函数一些参数,就能得到一个新函数

const add = x => y => x + y;const increment = add(1);const addTen = add(10);console.log(increment(2)) // 3console.log(addTen(2)) // 12

Compose (代码组合)

一个简单的 compose 函数如下

const compose = (f, g) => x => f(g(x));

可以看到, 代码执行顺序是从右向左

并且, 组合函数遵循结合律

// associativitycompose(f, compose(g, h)) === compose(compose(f, g), h);

举个 🌰​ 咯

const compose = (f, g) => x => f(g(x));const toUpperCase = x => x.toUpperCase()const excalim = x => x + '!'const logMidRes = x => console.log(x) || xconst convertString = compose(excalim, toUpperCase)const convertString2 = compose(compose(logMidRes, excalim), compose(logMidRes, toUpperCase))const a = convertString('welcome')const b = convertString2('welcome')// WELCOME WELCOME!console.log(a) // WELCOME!console.log(b) // WELCOME!

Pointfree style

函数不会提到其操作的数据, 如下

// not pointfree because we mention the data: nameconst initials = name => name.split(' ').map(compose(toUpperCase, head)).join('. ');// pointfreeconst initials2 = compose(intercalate('. '), map(compose(toUpperCase, head)), split(' '));const a = initials('hunter stockton thompson'); // 'H. S. T'const b = initials2('hunter stockton thompson'); // 'H. S. T'console.log(a)console.log(b)

以下为工具代码

// args 为实际使用数据 fn , 此时为数组, 展开(...)之后, 被 fn 调用, 调用后将返回的结果放入一个数组中, 以便下次可展开调用, 最后, 取出数组中唯一的值 const compose = (...fns) => (...args) => fns.reduceRight((res, fn) => [fn.call(null, ...res)], args)[0];function curry(fn) {const arity = fn.length;return function $curry(...args) {if (args.length < arity) {// 参数未达到使用条件, 如 split(' '), 添加操作数并返回return $curry.bind(null, ...args);}// 实际调用, 传入实际使用参数return fn.call(null, ...args);};}// give it a sep and we get a function back=>waiting for its str argument.const split = curry((sep, str) => str.split(sep));const intercalate = curry((str, xs) => xs.join(str));const map = curry((fn, f) => f.map(fn));const toUpperCase = x => x.toUpperCase()const head = x => x[0];

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。