参照透過性
同じ入力は常に同じ出力であること
特に関数において引数が同じなら常に同じ返り値になる特性を指すことが多い
参照
が透過
とは参照の状態に透明性がある。つまり参照を意識する必要がない状態を意味する
下記は参照透過性がある
// 引数x, yがそれぞれ1, 2なら常に返り値は3になる
function func(x, y) {
reutnr a + y;
}
下記は参照透過性がない
let x = 0;
// 変数xの状態は関数実行時までに変わっている可能性がある → 参照に透明性がない
function func1() {
x++;
return x;
}
// 下記は実行時刻によって返却値が異なる → 参照に透過性がない
function func2() {
const data = new Data();
return data;
}
副作用
ある関数の実行によって関数外部の状態が変更されること
// 下記関数は副作用がない
function func(x, y) {
reutnr a + y;
}
// 関数外部の変数iの状態を変更している → 副作用がある
let i = 0;
function func2() {
i++;
return i;
}
純粋関数
同じ引数で実行した場合常に返り値が同じ(参照透過性)
副作用を発生させない
参照透過性が好ましい理由
- 予期せぬバグが起きづらい
- 改修の際の影響範囲を特定しやすい
- テストしやすい
純粋関数へのリファクタリング
下記は副作用を含み、非参照透過性な関数
let i = 0;
// 出力は関数外部のiの状態によって異なる → 参照透過性が無い
function func() {
// 外部変数iの状態を変更している → 副作用の発生
i++;
// returnしていないのでテストしづらい
console.log(i)
}
func() // 1
func() // 2
func() // 3
// 引数で値を渡すようにすることで参照透過性と副作用の非発生化
// 値はreturnで返すことでテストがしやすくなる
function func(x) {
return x;
}
console.log(func(1)); // 1
console.log(func(2)); // 2
console.log(func(3)); // 3
参考