Day 21 - Handle Side Effect I

在介绍本篇我们先来复习一下先前在 pure function 那章提过的一些名词

  • Side Effect: 当呼叫函式时,此函式会改变外部物件的状态,则称这个函式有 Side Effect.
  • Pure function: 给定相同的输入,一定会得到相同的输出。并且不会产生任何 Side Effect.

但在现实开发中则无法避免这些 Side Effect 的操作,举几个例子,

  • 读取 / 写入 localStorage,
  • 将讯息写入 console,
  • 取得时间 (new Date),
  • 产生乱数 (Math.random),

所以今天就要讲讲在 Functional Programming 中,如何去处理这些 side effect

dependency injection

example

在还没开始介绍 IO 前,先来看看原本我们是如何写出 pure function, 没错,就是 dependency injection.

假设现在有一个函式,其功用是要取得 document.body 的高度,

function getBodyOffsetHeight() {
	return document.querySelector('body').offsetHeight;
}

const offSetHeight = getBodyOffsetHeight(); 

可以看到 getBodyOffsetHeight 是一个 impure function,因为 DOM 有可能随时改变,会使得每次呼叫 getBodyOffsetHeight 结果有可能会不一样,要如何把它变成 pure function 呢?

function getBodyOffsetHeightFromDOM($) {
	return $('body').offsetHeight;
}

const qs = document.querySelector.bind(document);

const offSetHeight = getBodyOffsetHeightFromDOM(qs); 

没错,可以直接把 document 直接当参数进行传入,这样就可以确保给定一样的输入就会有得到相同的输出,这样不就是一个 pure function 了嘛!!

advantage

这种方法的好处是让我们在进行 unit test 时,可以不用模拟一个专门测试的 DOM (ex: JSDOM),也就是让程序可可测试性增加。

const mockQS = () => ({ offsetHeight: 1000 });

const offSetHeight = getUserNameFromDOM(mockQS);

assert.strictEqual(offSetHeight, 1000, true)

disadvantage

虽然我们确保了函式是 pure function 跟可测试,但当我们是开发一个大型的 App,则导致 App 非常难以维护及阅读。

举例来说,由於函式要 pure, 所以我们在最外层的 function 注入所有需要的的 dependency,但如果这个函式里面是非常深层的,就必须要将参数不断传递,这将会导致我们的程序码非常难以维护。

const App = ($, localStorage, date, config, ... ) => {
    /** prop drilling */
}

小结

今天因为考驾照太忙了/images/emoticon/emoticon02.gif所以将原订计画稍加更改,明天将来介绍 IO Monad 是如何处理 Side Effect 的!

感谢大家阅读!

NEXT: Handle Side Effect - IO Monad


<<:  人脸辨识-day21 资料预处理--2

>>:  [Day 21]从零开始学习 JS 的连续-30 Days---阵列操作介绍 (上篇)

Day18 X Service Workers Cache

如果你听过 PWA,那麽对今天的主题ㄧ定不陌生,因为今天要讲的 Service Worker 就是...

Day 10 ( 中级 ) 雪花随风飘

雪花随风飘 教学原文参考:雪花随风飘 这篇文章会介绍,如何在 Scratch 3 里使用建立分身、绘...

[2021铁人赛 Day-02] 嵌入式学习模式 and 系统分类

引言 今天介绍嵌入式系统学习的模式,并说明未来的撰写模式 = ) 学习十字路口 学习新知识必定会有...

[C 语言笔记--Day25] 不只有一个 expression 的 macro

大纲 1. 不只有一个 expression 的 macro 2. 使用 code block 解决...

【D27】模组化#2:取三大法人期货交易资料

前言 整理股票每日交易资讯後,把三大法人资料(区分期货与选择权二类-依日期)也模组化,也可以用get...