📦

JavaScriptにおける再代入可能な変数の扱い方

2024/11/01に公開

調べたものとは?

再代入可能な変数を定義し、ある関数が実行されるたびにその変数に任意の数を加算する実装が必要になりました。

「状態」という概念を用いればhookscomposablesの中でuseStaterefを使い簡単に実装できます。しかし、それを使わないで実装したいな、と思ったのでchatGPTを使って調べてみました。

結果

まず問題あるのか?

JavaScriptにおいて再代入可能な変数を関数が実行されるたびに変更するのは一般的に問題ありません。

しかし、その扱いには注意が必要となります。変数が関数の外部にあり、関数実行のたびに更新されるような「状態」を持つ場合、変数の管理方法がコードの読みやすさや保守性に影響します。

再代入可能な変数の状態管理における注意点

JavaScriptでは再代入可能な変数を更新して状態を持たせることは可能ですが、以下のような注意が必要となります。

  1. スコープ管理:状態を持つ変数がグローバルスコープにある場合、予期せぬ変更や競合が生じる可能性があります。できるだけ変数のスコープを狭めることが望ましいです。
  2. 可読性:状態を持つ変数は、どこで変更されるのか分かりにくくなる可能性があります。予期せぬタイミングで変数が変わると、バグを招きやすくなります。
  3. 関数の副作用:内部で直接関係のない変数を更新する副作用を持つと、他の部分で再利用しづらくなる可能性があります。必要に応じて変数を更新する関数(例えば increment() など)を定義し、関数の実行後にその関数を呼び出すようにすると、可読性やメンテナンス性が向上します。

より良い状態管理の例

次のコード例は、外部変数 variable の管理を工夫した形です。

let variable = 0;

function hogeFunc() {
    // 関係のない処理
    console.log("Executing unrelated logic");
}

// variableを増やすための関数を別に定義する
function increment() {
    variable += 1;
}

// test関数実行後にincrementAを呼び出す
hogeFunc();
increment();
console.log(variable); // variableが+1された状態で出力

JavaScriptでの状態管理のための代替アプローチ

状況によっては、以下のような管理方法も検討すると良いでしょう。

クロージャを用いた変数のカプセル化:

変数を関数内に閉じ込めて外部から直接アクセスできないようにすることで、意図しない変更を防ぎます。

function stateManager() {
  let variable = 0;
  
  return {
    increment: function () {
      return variable += 1;
    },
  };
}

オブジェクトやクラスを利用した管理:

変数variablesが増加する機能を持つオブジェクトやクラスを定義すると、状態の管理がしやすくなります。

const stateManager = {
    variable: 0,
    increment() {
        this.variable += 1;
    }
};

function hogeFunc() {
    console.log("Executing unrelated logic");
}

// hogeFuncの後にincrementを呼ぶ
hogeFunc();
stateManager.increment();
console.log(stateManager.variable); // variableが+1された状態で出力

関数引数で状態を受け渡す方法

場合によっては、状態を関数の引数として渡し、戻り値で更新する方法も有効です。これにより、関数の副作用がなくなり、this も不要になります。

function increment(value, amount = 1) {
    return value + amount;
}

let variable = 0;
variable = increment(variable); // Aに1を加える
console.log(variable); // 出力: 1

variable = increment(variable, 3); // Aに3を加える
console.log(variable); // 出力: 4

まとめ

JavaScriptで再代入可能な変数に関数実行のたびに変更を加えること自体は可能ですが、スコープ、関数の副作用、可読性を考慮し、状況に応じてクロージャやオブジェクトを活用するのが望ましいです。

Discussion