JavaScript Tips | 基本・共通ユーティリティ:汎用 – no-op 関数

JavaScript JavaScript
スポンサーリンク

no-op 関数ってそもそも何?

「no-op(ノーオペ)」は no operation の略で、
「何もしない関数」 のことです。

JavaScript だと、いちばんシンプルな形はこれです。

function noop() {}
JavaScript

またはアロー関数でこう書いても同じです。

const noop = () => {};
JavaScript

呼んでも何も起きません。

noop(); // 何も起きない
JavaScript

「何もしないなら、そもそも呼ばなきゃいいじゃん」と思うかもしれませんが、
業務コードでは 「関数“が必要な場所”に、とりあえず置いておくダミー」 として、ものすごくよく使います。


なぜ「何もしない関数」が業務で役に立つのか

「関数が必須だけど、今はやることがない」場面

例えば、あるライブラリがこういうオプションを要求してくるとします。

initialize({
  onSuccess: ???,
  onError: ???,
});
JavaScript

仕様として「onSuccessonError は関数であること」と決まっている。
でも、今の画面では「成功しても失敗しても、特に何もしなくていい」。

そんなときに nullundefined を渡すと、ライブラリ内部でこう書かれていた場合に落ちます。

options.onSuccess(result); // undefined を呼ぼうとしてエラー
JavaScript

ここで noop の出番です。

initialize({
  onSuccess: noop,
  onError: noop,
});
JavaScript

これなら、「ライブラリ側は安心して onSuccess() を呼べる」「こちらは何も起きてほしくない」という両方を満たせます。


no-op 関数を「デフォルト値」として使う

オプションのコールバックに対する使い方

自分で関数を設計するときにも、no-op はよく使います。

function fetchUser(options = {}) {
  const {
    onSuccess = noop,
    onError = noop,
  } = options;

  // 以降は「必ず関数が入っている」前提で書ける
  fakeApiCall()
    .then((user) => {
      onSuccess(user);
    })
    .catch((err) => {
      onError(err);
    });
}
JavaScript

呼び出し側は、必要なときだけコールバックを渡せばよくなります。

fetchUser({
  onSuccess(user) {
    console.log("ユーザー取得:", user);
  },
});
JavaScript

onError を渡していなくても、内部では noop が入っているので、
onError(err) を呼んでも何も起きず、エラーにもなりません。

ここでの重要ポイントは、
「呼び出し側の“省略”を許しつつ、内部では“常に関数がある前提”で書けるようにする」
という設計を、no-op が支えていることです。


UI コンポーネントと no-op の相性

イベントハンドラの「とりあえずの中身」として

UI コンポーネントでも、no-op はよく使います。

function Button(props) {
  const {
    onClick = noop,
    onFocus = noop,
  } = props;

  function handleClick(event) {
    onClick(event);
  }

  function handleFocus(event) {
    onFocus(event);
  }

  // 仮の JSX 風
  return `<button>...</button>`;
}
JavaScript

親コンポーネントが onClick を渡さなくても、
Button 側は「必ず関数が入っている」前提で onClick() を呼べます。

これにより、

「毎回 if (props.onClick) とか typeof === "function" とか書かなくていい」
「“イベントが来たらとりあえず呼ぶ”というコードがシンプルになる」

というメリットが生まれます。


no-op 関数をユーティリティとして定義しておく

プロジェクト共通の「何もしない」を一箇所に

毎回 () => {} と書いてもいいのですが、
プロジェクトとしては一箇所にまとめておくと分かりやすくなります。

// utils/function.ts など
export const noop = () => {};
JavaScript

これをどこからでもインポートして使うイメージです。

import { noop } from "./utils/function";

const handler = noop;

function doSomething(callback = noop) {
  callback();
}
JavaScript

「このプロジェクトでは、noop が“公式の何もしない関数”」という共通認識ができると、
コードレビューでも「ここは何もしない前提なんだな」とすぐに伝わります。


no-op と「安全処理」のつながり

no-op 自体は「何もしない」だけですが、
「何もしない“こと”を明示する」 という意味で、安全処理の一部です。

「ここはコールバックがなくても落ちてほしくない」
「ここはイベントが来ても、特に何もする必要がない」

そういう場所に no-op を置くことで、

「呼び出し側の都合で何も起きない」のか
「そもそもバグで関数が渡っていない」のか

を区別しやすくなります。

「意図的な“何もしない”」をコードとして表現する。
そのための最小単位が no-op 関数です。


小さな練習で感覚をつかむ

次のようなコードを書いて、no-op の有無で挙動がどう変わるか試してみてください。

function runTask(callback) {
  // パターンA: そのまま呼ぶ
  callback();

  // パターンB: デフォルト値に noop を使う
  // const cb = callback ?? noop;
  // cb();
}

runTask(() => console.log("実行された"));
runTask(); // ここでどうなるか?
JavaScript

「そのまま呼ぶ」と「no-op をデフォルトにする」の違いを体感すると、
「何もしない関数」が、実はコード全体の安定性を支える大事なピースなんだ、という感覚がつかめてきます。

タイトルとURLをコピーしました