「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」
本篇带来 FP 函数式编程思想在 JS【循环】中的应用。
闲言少叙,冲 (づ ̄3 ̄)づ╭~
通常,写一个循环:
for (let i=9; i<=22; i++) {
// do something with i
}
或者:
let i = 9;
while (i <= 22) {
// do something with i
i++;
}
这样写有什么问题吗?
说有,也是有的 QAQ
<
号;
所以,我们尝试用 FP 函数式编程思路对循环做下改造~
改造后的期望类似这样:
range(9, 22).forEach(i => {
/* do something with i */
})
range 函数实现:
const range = (from, to) => {
const arr = [];
do {
arr.push(from);
from++;
} while (to >= from);
return arr;
};
range(9,22) 展开就是 [9, 10, 11, … 22],如果,想要反转数组,比如:range(12,4) 展开是 [12,11,10...4]
const range = (from, to, step = Math.sign(to - from)) => {
const arr = [];
do {
arr.push(from);
from += step;
} while ((step > 0 && to >= from) || (step < 0 && to <= from));
return arr;
};
range(12,4)
这样,我们就做了一层简单的封装!
还有一个问题 —— 目前这样写,循环不受控制。即我们不能随意停止循环或者跳出循环;
为了解决这个问题,尝试采用 .some(fn) 来代替 .forEach(fn);
some()
方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。e.g.
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
只要 Fn 函数返回 false ,循环将继续;当它返回 true 时,循环将结束。
同时借助 generators,每次调用,它会产生一个返回值;
range() 函数演变如下:
function* range(from, to, step = Math.sign(to - from)) {
do {
yield from;
from += step;
} while ((step > 0 && to >= from) || (step < 0 && to <= from));
}
for (const i of range(9, 22)) { i => {
...
...
if (someCondition) continue;
...
if (somethingElse) break;
...
...
}
}
// 或者赋值一个数组
const arrayFrom9To22 = [...range(9, 22)];
// this produces [9, 10, 11, ... 22]
通过这样的方式,甚至可以赋值一个数组 range(9,999999999999) 内存不会爆掉,因为它通过 generators 生成,是惰性的;MDN-迭代器 有说明:
Javascript中最常见的迭代器是Array迭代器,它只是按顺序返回关联数组中的每个值。 虽然很容易想象所有迭代器都可以表示为数组,但事实并非如此。 数组必须完整分配,但迭代器仅在必要时使用,因此可以表示无限大小的序列,例如0和无穷大之间的整数范围。
小结:通过 FP 函数式编程思维对“循环”进行了简单封装,使得代码的可读性和可扩展性都增强了一些,针不戳 👍
OK,以上便是本篇分享~
我是掘金安东尼,输出暴露输入,技术洞见生活,再会~~