なんで関数を定義するんだろう
- 同じ意味を持つロジックに名前をつけてあげることで認識をしやすくできるよ
- 同じことをしたい場所で同じ挙動をすることを保証するできるよ
関数のない例
function showExcel(user) {
downloadExcel(`${user.firstName} ${user.lastName}`)
}
function showHtml(user) {
renderHtml(`${user.firstName} ${user.lastName}`)
}
- ユーザの表示の仕様は苗字/名前を空白つなぎで表すことです。
- 仕様が変更したらshowExcel/showHtmlどちらにも必要になりますね。
- Htmlのほう変更が漏れてました><が起こり得ますよね!
- これが関数を定義することによって回避できるんです
関数を定義してみる
function showUser(user) {
return `${user.firstName} ${user.lastName}`
}
function showExcel(user) {
downloadExcel(showUser(user))
}
function showHtml(user) {
renderHtml(showUser(user))
}
- showUserに苗字/名前を空白つなぎで表す 仕様を満たすロジックを書いたよ!
- ユーザ表示の仕様が変わって苗字だけでよくなったときはshowUserを変更したらいいね!一箇所の変更で済むね!
- 同じ仕様は同じロジックから呼び出されるというのをプログラムで表現できたぞ!
無名関数の乱用は避けて関数に名前をつけて定義しよう
- これをよんでパッとselectActiveAdminUsersByGroupはなにをするかわかるかな?
- filterに渡されている無名関数の中はなにをしているんだろう...と考えるので時間がかかるね
function selectActiveAdminUsersByGroup(users, group) {
return users
.filter(user => user.status === Active)
.filter(user => user.groupId === group.id)
.filter(user => user.role === God || user.role === Admin)
}
関数に分けて定義してみる
- こうしたらfilterに渡している関数名からなにをするロジックなのかわかりやすいね
- isActiveUser/isUserInGroup/isAdminUserはselectActiveAdminUsersByGroup以外の関数でも今後使えそうで便利だね!
function isActiveUser(user) {
return user.status === Active
}
function isUserInGroup(user, group) {
return user.groupId === group.id
}
function isAdminUser(user) {
return user.role === God || user.role === Admin
}
function selectActiveAdminUsersByGroup(users, group) {
return users
.filter(isActive)
.filter(user => isUserInGroup(user, group))
.filter(isAdminUser)
}