JavaScript: 2005年9月アーカイブ

JavaScript を使っていると、必然的にブラウザ毎の実装の違いを吸収した関数を用意する。 例えば指定した ID で HTML 要素(レイヤー) を取得する場合、いつも以下のように書いていた。この関数は呼び出される毎にブラウザの特徴を嗅ぎ分けて、それにふさわしい処理を行おうとしている。

/**
 * 指定した ID を持つ HTML 要素を取得する
 *
 * @param 	string	ID
 * @return	object	HTML 要素
 */
function getLayer(id)
{
	var element = null;

	if (document.getElementById)
	{
		element = document.getElementById(id);
	}
	else if (document.all)
	{
		element = document.all(id);
	}
	else if (document.layers)
	{
		element = document.layers[id];
	}
	
	return element;
}

ここで気になるのが、関数を呼び出す度にブラウザを嗅ぎ分けて、それにふさわしい処理を行おうとしている点だ。嗅ぎ分けた結果を変数に入れてしまえば、分岐に掛かる時間はちょっとだけ減る。だがいまいちパッとしない。という事で書いたのが次のコードだ。

/**
 * 指定した ID を持つ HTML 要素を取得する
 *
 * @param 	string	ID
 * @return	object	HTML 要素
 */
getLayer =
	  (document.getElementById)
	? function (id) { return document.getElementById(id); }
	: (document.all)
	? function (id) { return document.all(id); }
	: (document.layers)
	? function (id) { return document.layers[id]; }
	: function (id) { return null;}

ごちゃごちゃとしていて見辛いが、やってる事は getLayer というよく判らない変数へ、ブラウザにふさわしい無名関数を入れてやっている。これできちんと期待通りに動いてくれる。この getLayer というグローバル変数も、最初の関数 getLayer も、window オブジェクトのプロパティであるのを利用している。次に例を書こう。

function XXX() { hogehoge; }

というコードは、

XXX = function () { hogehoge; }

と等価である。もう少し書こう。

function neko()
{
	alert("∧∧");
}

neko();         // alert("∧∧")
window.neko();  // alert("∧∧")


neko = function ()
{
	alert("にゃー");
}

neko();         // alert("にゃー")
window.neko();  // alert("にゃー")


var neko = "猫";

neko();			// エラー。neko is not function
window.neko();	// エラー。neko is not function

関数を定義するという事は、オブジェクトのプロパティに無名関数を登録している、と考えるといいかも知れない。

こうやって実行時に関数を定義してしまえば、余計なブラウザの嗅ぎ沸けを省く事が出来る。それによってCPUはちょっぴり(本当に、本当に少し)消費電力を少なくする。実に経済的だ。郊外のショッピングセンターで近所のスーパーより1円安いレタスを見付けたら、リッター130円のガソリンを使って車を走らせる事をためらってはならない。

このアーカイブについて

このページには、2005年9月以降に書かれたブログ記事のうちJavaScriptカテゴリに属しているものが含まれています。

前のアーカイブはJavaScript: 2005年7月です。

次のアーカイブはJavaScript: 2006年6月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.12