如果OOP是以物件为主那FP就是以Function作为主体来思考。但也须有人会好奇 Function 这种语法很多程序语言都有支援但FP这个概念为什麽很少听过,除了因为语言特性限制我个人是认为FP进阶的概念实在是太抽象,且充满许多数学推演的过程。
但这个状况直到近几年慢慢的有变化了,如果刚好你是前端工程师的话应该知道 FP 应该是近几年前端领域的buzz word了,前端中有很多借监FP概念的实作案例:Promise(参考monad)、reudx(pure function)、react hook (使用closure实作)
听起来很厉害那我们该如何开始?基本上有几个基础概念可以聊聊
所谓Side effect就是指在functtion中除了回传外还会造成其他影响的行为,基本上side effect都很有可能是造成Bug的主要原因。
我们来看看常见的Side effect有哪些包括但不限於:
为什麽他们会造成Bug?举几个例子我们可能会因为没有管理好非同步事件,导致我们资料存取失败进而导致画面异常甚至crash又或者我们更改了全域变数导致其他地方产生了预期外的结果等等。
但毕竟我们无法完全消灭side effect,所以我们要想几个方法可以好好的管理,而这也是 FP 主要目标,或者可以说是程序设计的目标。
pure function如同他的名字就是一个纯净的函式:相同的输入永远只会得到相同的输出,且没有side effect。
int addNumber(x, y) => x + y;
int multNumber(x, y) => x * y;
bool isOdd(x) => x % 2 != 0;
在真正讲解Higher-order function(HOF)之前我们必须先知道一个名词First-class Function,意即函式跟一般的值一样,可以被存在变数里、可以做为函式的参数或者回传值。
前几篇文章一直提到的callback function这个概念,它在早期的JS中很常运用在非同步操作时,
而callback的形式大概会像是:
void y(Function x){
//some stament
x()
}
我们将一个函式 x
传进去一个函式 y
里,当 y
执行时会在里面执行 x
,这已经满足是Higher-order function的条件了。
HOF在定义上是:一个可以接受以函式作为参数或者最後会回传函式的函式。
运用这些特性可以很简单的让我们各个function compose在一起。
final a = addNumber(1,multNumber(2,3)); //7
或者是在 List
操作中很常看到的:
final ListA = [1, 2, 3, 4, 5, 6];
print(ListA.map(addTen).toList()); // [11, 12, 13, 14, 15, 16]
print(ListA.fold<int>(0, addNumber)); // 12
print(ListA.where(isOdd).toList()); // [1, 3, 5]
print(ListA.map(addTen).fold<int>(0, addNumber)); // 81
print(ListA.where(isOdd).map(addTen).fold<int>(0, addNumber)); //39
从上面了例子我们可以简单地看出这个 List
怎麽被操作例如这行
ListA.where(isOdd).map(addTen).fold<int>(0, addNumber);
可以看出是先挑出奇数的数字然後将剩下的每个都加10然後在全部加总,这种我们不必管实际上「如何」操作,而只关注我要去做「什麽」的概念又被称为:declarative programming
也拿来实作 curry function (柯里化):
Function curryiedAdd(int x) => (int y) => x + y;
final addTen = curryiedAdd(10);
final b = addTen(2);
print(b);
//12
这边可以看到 curryiedAdd
是会回传一个function的function,所以我们在
final addTen = curryiedAdd(10);
这里的 addTen
是一个function
而我们也能这样呼叫 curry function
final c = curryiedAdd(2)(10);
print(c);
// 12
今天的程序码:
https://github.com/zxc469469/dart-playground/tree/Day13/FP
这篇文章也只是稍微提到 FP中的概念,但实际上还有很多进阶的概念或者议题:point-free、functor、monad。但其实在没了解这些之前我们还是能享受到一定的好处,像是function composition 及declarative programming这种可以简化程序码或者提升易读性的概念,又或者是好测试的pure function。
而我自己在开发网页前端时会尽量的运用FP的概念在实作,像是有一些function的行为会同时需要上层component及子component的变数且是在子component被呼叫。
通常我会将这类function curry起来将一些上层component的变数或函式(通常是不想往下传的值像是:setState之类的function)包装起来,这样子component就可以少开一些props。
<<: [Day25] Esp32s + IFTTT + LINE
好 那今天就会完成这个小专案 可能 CSS 的部份写的没有很好 ouo 读者可以自行修改 还是再放一...
今天继续介绍 NetSuite 几个基本的 Glossary, 这些 Glossary 经常会出现在...
其实在开赛前,我有规划一些软性书单,想说在忙碌或想要休息时,可以拿来挡一下。但我今天早上真正 rev...
适用人员: 技术人员(开发人员)。 适用法规: 资通安全责任等级分级办法 - 附表十资通系统防护基准...
由於查询部分的篇幅相较於前几者较多,因此将查询的部分独立出来写 另外这边写的只有一些基础的操作,像是...