isNaN関数の落とし穴

は?nullも空文字も空白も数値なの?

isNaN(null) => false
isNaN('') => false
isNaN(' ') => false
isNaN(undefined) => true


というわけで入力された値が数値かどうかを調べたい時などは isNaN 関数だけではとても使い物にならないので、 trim 後に有効な長さがあるか調べたり正規表現で調べる必要がある。


参考:JavaScript のムカつくコードを集めたサイト
http://wtfjs.com/

window.onloadよりdom:loadedを使う

window.onloadはページの読み込みが終了した時点でイベントが呼び出されるため、この関数内に時間がかかる処理を置くと予想以上にページの描画が終わらない場合がある。
このイベントよりもっと速くて有用なイベントとして、dom:loaded がある。これは、ブラウザがHTMLをパースしてDOMツリーを構築し終えた時点で発火するイベント。つまりこのイベント後ならば document.getElementById を行っても要素が見つかりませんエラーが出なくなる。


使い方

document.observe("dom:loaded", 
    function() {
        //logic
    });


注意点として、DOMツリーの構築が終わっていても描画が終わっていない場合があるので、このイベント内で document.getElementById('someId').style.height のようなプロパティを見ても0やnullが入っている場合がある。

描画時にスタイル関連を操作したい場合は、dom:loadedイベント内で前処理をしておき、window.onloadイベント内でスタイルを適用するという形にするのが望ましい。前処理ができるような場合に限るけど。

Javascriptで同じ名前の関数を再定義

同じ空間内で同じ名前の関数を定義しても、後のほうに定義した関数が元の定義を上書きする。


コード例

	function f()
	{
	    alert('before');
	}

	function f()
	{
	    alert('after');
	}
	f(); //after


んでこれ実験して初めて知ったのだけど、どの時点でもf();を呼んだら after が表示されるのね。
つまりコードを実行する前に関数の定義がエンジンに登録されるわけだ。

	f(); //after
	function f()
	{
	    alert('before');
	}

	f(); //after
	function f()
	{
	    alert('after');
	}
	f(); //after


これを活用してある程度汎用的なロジックをJSファイルに記述して、一部だけロジックの修正をしたい場合に各ページごとに関数の定義を上書きして使うというStrategyパターンみたいなことができるようになる。


言語的にオーバーロードはできないので同じ名前ならば引数が違えど定義が上書きされる。

	f(); //after
	function f()
	{
	    alert('before');
	}

	f(); //after
	function f(args)
	{
	    alert('after');
	}
	f(); //after


オーバーロードを使いたい場合は関数内で暗黙的に作成されるオブジェクト、argumentsを用いる。

	function f()
	{
 	    if(arguments.length == 1)
                alert("arguments.length = 1 v1:"+arguments[0]);
  	    else if(arguments.length == 2)
                alert("arguments.length = 2 v1:"+arguments[0]+" v2:"+arguments[1]);
	}
		
	f('value'); //arguments.length = 1 v1:value
	f('value1','value2'); //arguments.length = 2 v1:value1 v2:value2