関数化について


このページは当時ボツになったもの。再編集に伴い、復活させてみた。

←Back


■効率の良い関数化って?

効率の良い汎用的な関数(function)を作るには、共通している処理はどこかをいかにうまく見つけられるか、がほとんどを占めます。

常に共通してる(不変である)処理は、無条件に関数行きです。今回の例では、「ブラウザを選り好みする」「スタイルシートを切り替える」「▲と▼を書き換える」に相当します。

不変でなくとも、ありうる変化が二者択一、三者択一のような少数であれば、やはり関数に放りこんで、if 〜 else で分岐させます。
今回の例では、「スタイルシートの値が "表示" であれば "非表示" に、"非表示" であれば "表示" にする」に相当します。「▲と▼を書き換える」も含まれますね。

そして、<div> のID名のような、常に不定である部分だけを引数にします。


■関数の関数化

「効率の良い関数化」を煮詰めていくと、関数の関数化が必要になってきます。

//ID名から(それぞれの方法で)オブジェクトを取得して返すだけの関数
function getObj(name) {
  var obj;
  if (document.all) //IE
    obj = document.all(name);
  else //Netscape
    obj = document.getElementById(name);
  return obj;
}

function clickMenu(idName, spanObj) {
  if (brwCheck) {
    with (getObj(idName).style) {
………

IE4と Netscape6 ではオブジェクトを取得する方法が違うので、いちいち分岐させていたらキリがありません。そこで、取得するだけの専用関数を作ることで、本体をより簡潔化することができます。
スクリプトが広範囲に及ぶと、「関数の関数化」はどうしても必要になってきます。特にDHTMLでは、必要になる局面が非常に多いです。関数の関数化の関数化なんてことも普通にあります。

これをどんどん追い求めると「クラス」に辿りつくのですが、ここでは割愛します。


■実例

たとえばこんな関数を作って、いちいち document.write() と書く手間を省くことができます。

function wri(writeText) {
  document.write(writeText);
}

wri("文字を書き出す");

これは、document.write("文字を書き出す"); としても結果は同じです。
これを「関数の関数化」して、さらに進化させてみると、

ここでの getWinObj() のように、「ウィンドウオブジェクトを取得する」部分だけをさらに分離し、他の関数と共用させれば、もっと効率が良くなりますよね。このような、プログラムをひとつひとつの短い処理に細分化することを、一般に「モジュール化」と言います。
上手にモジュール化されたプログラムは、管理も容易で、汎用性にも優れています。

その極意(?)が、先にも言った共通している処理はどこかをいかにうまく見つけられるか、にかかってます。オブジェクトの取得など、特に多く使われるものを集めてひとつのファイルにまとめれば、DLLのような使い方ができます。


■ご注意

記述の効率化と処理の効率化は別ものなので、その辺は注意が必要です。

上の7行と下の2行は同じ処理ですが、下側は (display == "block") を2回評価しないといけないので、処理上の効率はかえって悪くなります。


■三項演算子

ちなみに、たびたび出ている … ? … : …; という構文は「三項演算子」というもので、

a = b ? c : d;

  ↓ 分解

if (b)
  a = c;
else
  a = d;

…と同じ意味です。ご存知かもしれませんが、念のため…。



■ このページについて

このページは、質疑応答掲示板で使用した回答の残骸です。検索エンジンに捕まったりリサイクルしたりすることもあろうので、なんとなく残してあります。広く公開しているページではありませんが、第3者の閲覧を禁止するものでもありません。
恒久的なURIは保証できないものの、よほどのことがない限り削除されることはないでしょう。心配性な人はページの保存をおすすめします。(IEは mht 形式でないと保存できないかも)