Aikido

関数の引数をオーバーライドしてはいけない理由:混乱とデバッグ問題の防止

読みやすさ

ルール

オーバーライド オーバーライド 関数の 引数をオーバーライドしない。
再割り当て 関数の 引数  を混乱させる
呼び出し側 そして デバッグ デバッグ を困難にする。

対応言語 45+

はじめに

関数のパラメータを再割り当てすると、関数内の引数の値が変更され、任意の時点でパラメータが保持している値が不明確になります。デバッグの際、パラメータが呼び出し元から渡された値を保持しているかどうかを信頼することはできません。これは、コードを読む人に混乱を引き起こし、実行中にパラメータの値が変化するため、バグの追跡が困難になります。

コード例

非準拠:

function processUser(user) {
    if (!user) {
        user = { id: null, name: 'Guest' };
    }

    user = { ...user, processedAt: Date.now() };

    if (user.age < 18) {
        user = { ...user, restricted: true };
    }

    return user;
}

なぜそれが間違っているのか: 会社情報 ユーザー パラメータが何度も再割り当てされるため、関数全体を読まなければ、元の呼び出し元が何を渡したのかを知ることができない。デバッグでは、実際の入力ではなく、変更された値が表示されるため、問題をソースまで遡ることが難しくなります。

✅ 準拠:

function processUser(user) {
    const currentUser = user || { id: null, name: 'Guest' };

    const processedUser = {
        ...currentUser,
        processedAt: Date.now()
    };

    if (currentUser.age < 18) {
        return { ...processedUser, restricted: true };
    }

    return processedUser;
}

なぜこれが重要なのか: 新しい変数カレントユーザー, 処理ユーザー)が中間値を保持する一方で、オリジナルの ユーザー パラメーターは変更されません。デバッガは実際の入力値を表示し、コードは名前付き変数による変換を明確に追跡する。

結論

パラメータを再割り当てする代わりに、変換に新しい変数を使う。こうすることで、データフローが明示的になり、デバッグのために元の入力を保持することができる。変数宣言が増えることによる若干の冗長さは、可読性とデバッグのしやすさの向上によって相殺される。

よくある質問

ご質問は?

デフォルトのパラメータ値についてはどうですか?

デフォルト・パラメーター(function process(user = {}))は、再割り当てとは異なる。引数が未定義の場合に値を提供するだけで、既存のパラメータを再割り当てするわけではありません。省略可能な引数にはデフォルト・パラメータを使用しますが、関数本体内で再割り当てしないでください。

これはプリミティブとオブジェクトのパラメータに適用されるのか?

はい、両方です。プリミティブ(数値や文字列)を再割り当てすると、ローカル参照が変更され、混乱が生じます。オブジェクトの再割り当ては参照を完全に置き換えますが、オブジェクトのプロパティ(user.name = 'x')を変更することは、不変性とは別の問題です。

入力のノーマライズやクリーンが必要な場合は?

const cleanedInput = normalizeInput(input). 正規化された値のために新しい変数を作成する。これにより、関数が入力を変換することが明確になり、デバッグ時に元の値とクリーニングされた値の両方が表示されます。

パラメータ・プロパティの変更は?

プロパティの変更(user.name = 'x')は、パラメータ自体の再割り当てとは異なる。しかし、パラメータを変更することは、副作用を引き起こすという問題があります。パラメータは不変なものとして扱い、変更された新しいオブジェクトを返すようにしましょう。

まずは無料で体験

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要。