私自身結構シマッタしちゃうので。

  1. 尻カンマ注意

    以下のコードはFireFoxでは動きますが、Internet Explorer (以下IE)では問題になります。

      var theObj = {
            city : "Boston",
            state : "MA",
      }
    

    最後にカンマが入らないよう注意しましょう。

  2. 浮気なthisは何を見てるやら

    以下のコードで、thisは何を指しているでしょうか。

    <input type="button" value="Gotcha!" id="MyButton" >
    <script>
    var MyObject = function () {
        this.alertMessage = "Javascript rules";
        this.ClickHandler = function() {
            alert(this.alertMessage );
      }
    }();
    document.getElementById("theText").onclick =  MyObject.ClickHandler 
    </script>
    

    これは、ClickHandler()がどう呼ばれたかによって変わってしまいます。MyObject.OnClick()を呼べば"Javascript rules"が表示されるのに、MyButtonをクリックしても"undefined"としか表示されません。これを防ぐには、以下のようにthisをローカル変数に保存して、それを渡すようにします。

    <input type="button" value="Gotcha!" id="theText" >
    <script>
    var MyObject = function () {
        var self = this;
        this.alertMessage = "Javascript rules";
        this.OnClick = function() {
            alert(self.value);
        }
    }();
    document.getElementById("theText").onclick =  MyObject.OnClick
    </script>
    

    var selfvarをくれぐれもお忘れなく。

  3. 身元詐称

    グローバル変数名とHTMLのIDが重ならないよう注意しましょう。

    <input type="button" id="TheButton">
    <script>
        TheButton = get("TheButton");
    </script>
    

    Fifefoxでは問題ありませんが、IEでは未定義オブジェクトエラーが出てしまいます。

  4. 文字列置換で最初のマッチしか置換されない
         var fileName = "This is a title".replace(" ","_");
    

    結果は"This_is a title"。これが期待した結果ならいいのですが、全部置換した場合には、gを指定しなければなりません。

        var fileName = "This is a title".replace(/ /g,"_");
    
  5. MouseOutがMouseInになったり

    ブロック要素が重なった場合、ある要素におけるMouseOutがその外の要素のMouseInになったりして大変ややこしいことになったりします。とくにコンテキストメニューを実装する場合などにそうなったりします。

    これを防ぐ一番簡単な方法は、YUIなど専用ライブラリを使うことです。

  6. ParseIntのしゃっくりを止める

    ParseInt()は使えます。文字列の中に、数字以外のものが入っていても期待どおりに動きます。例えばこんな風に。

    var height = parseInt("200px")
    

    ところが、数字の頭に0がついていると、ParseInt()は問答無用でそれを8進数として扱います。以下のような場合、それは困ります。

        month = "09"
        var monthInt = parseInt(month) // 9でなくて0
    

    この場合でも、基数を指定してやることで、10進法を強制することが出来ます。

      var monthInt = parseInt(month , 10);
    
  7. まわりすぎなforループ
    var arr = [5,10,15]
    var total = 1;
    for (var x in arr) {
        total = total * arr[x];
    }
    

    これでarrの中身を全てかけ算できるはずですが、"NaN"が出てきてしった時にはまいりました。arrにたとえばmyfunc()といった関数オブジェクトまで入っていると、それまでforループで代入されてしまうのがその原因でした。

    配列は以下のようにきちんとまわしましょう。

    for (var x = 0; x < arr.length; x++) {
        total = total * arr[x];
    }
    

    あるいは、

    for (var x = 0, l = arr.length; x < l; x++) {
        total = total * arr[x];
    }
    
  8. イベントハンドラの落とし穴

    イベントハンドラを設定するのに、以下のようにしてはいけません。

    window.onclick = MyOnClickMethod
    

    理由は以下のとおりです。

    1. 他のイベントを上書きしてしまいます。他者の作ったJavaScriptライブラリを使う場合など、特に注意が必要です。
    2. IEでは特定の状況下でメモリーリークを引き起こします。

    その代わりに、YUIなどを利用しましょう。

    YAHOO.util.Event.addListener(window, "click", MyOnClickMethod);
    

    [訳注:この件に関しては、404 Blog Not Found:javascript - Douglas Crockford on DOMも参考に]

  9. Focus Pocus [訳注:Hocus Pocusのもじり]

    DOMオブジェクトを生成してから、そこにfocusを当てたくなることはよくあります。

    var newInput = document.createElement("input");
    document.body.appendChild("newInput");
    newInput.focus();
    newInput.select();
    

    しかし、このやり方はIEではうまく行きません。IEでは、DOMオブジェクトを生成した時点では、オブジェクトは有効になっていないのです。解決法として、focusを遅延させるという手があります。

    var newInput = document.createElement("input");
    newInput.id = "TheNewInput";
    document.body.appendChild("newInput");
    setTimeout("document.getElementById('TheNewInput').focus(); 
    document.getElementById('TheNewInput').select();", 10);
    

    [訳者添削:あるいは]

    var newInput = document.createElement("input");
    newInput.id = "TheNewInput";
    document.body.appendChild("newInput");
    setTimeout(function(){
        document.getElementById('TheNewInput').focus(); 
        document.getElementById('TheNewInput').select();
    }, 10);
    

Dan the JavaScripter