點燈坊

失くすものさえない今が強くなるチャンスよ

如何同時判斷多個 undefined ?

Sam Xiao's Avatar 2020-02-14

Operator 雖然精簡,若善用 FP 的 Declarative Programming Paradigm,其可讀性可能更高。

Version

macOS Catalina 10.15.3
VS Code 1.42.0
Quokka 1.0.277
Ramda 0.26.1

&&

let data0 = undefined
let data1 = undefined
let data2 = undefined

let f = x => y => z => x === undefined && y === undefined && z === undefined

f(data0)(data1)(data2) // ?

若要同時判斷多個值都是 undefined ,最標準寫法就是使用 === undefined&&,可讀性雖高但很冗長。

undefined000

Falsy Value

let data0 = undefined
let data1 = undefined
let data2 = undefined

let f = x => y => z => !x && !y && !z

f(data0)(data1)(data2) // ?

藉由 ECMAScript 的 falsy value 特性,可使用 ! 加以簡化,但須注意 false0 與 empty string 亦為廣義 falsy value,有誤判可能性。

另外就語意而言,!undefined 有段距離,較難直接從 code 得知判斷 undefined,這算 ECMAScript 獨特語言特性。

undefined001

Ramda

import { all, isNil } from 'ramda'

let data0 = undefined
let data1 = undefined
let data2 = undefined

let f = x => y => z => all(isNil)([x, y, z])

f(data0)(data1)(data2) // ?

Ramda 的 isNil() 可判斷值是否為 undefinednullall(isNil) 其語義相當於 all undefined,且由於將值全部合併成 array,不會到處充斥 undefined 相當精簡。

undefined002

||

let data0 = undefined
let data1 = 1
let data2 = 2

let f = x => y => z => x === undefined || y === undefined || z === undefined

f(data0)(data1)(data2) // ?

若要同時判斷多個值其中之一為 undefined ,最標準寫法就是使用 === undefined!!,可讀性雖高但很冗長。

undefined003

Falsy Value

let data0 = undefined
let data1 = 1
let data2 = 2

let f = x => y => z => !x || y || z

f(data0)(data1)(data2) // ?

藉由 ECMAScript 的 falsy value 特性,可使用 ! 加以簡化,但須注意 false0 與 empty string 亦為廣義 falsy value,有誤判可能性。

另外就語意而言,!undefined 有段距離,較難直接從 code 得知判斷 undefined,這算 ECMAScript 獨特語言特性。

undefined004

Ramda

import { any, isNil } from 'ramda'

let data0 = undefined
let data1 = 1
let data2 = 2

let f = x => y => z => any(isNil)([x, y, z])

f(data0)(data1)(data2) // ?

Ramda 的 isNil() 可判斷值是否為 undefinednullany(isNil) 其語義相當於 any undefined,且由於將值全部合併成 array,不會到處充斥 undefined 相當精簡。

undefined005

Conclusion

  • &&|| 搭配 ! 常讓人難以思考,尤其人類不擅長 反向邏輯,透過 FP 的 function 可用更口語法方式表達,可讀性更佳

Reference

Ramda, all()
Ramda, any()
Ramda, isNil()