JavaScriptのWith文を使っちゃいけない訳
「JavaScript: The Good Parts」の中で「With文使うんじゃねぇよ、ボケ!」と怒られたことは覚えているのだけれど、この前唐突に理由を聞かれて思い出せなかったのでおさらいしておく。
理由:with文の中で該当しないプロパティやメソッドを呼ぶと、プロトタイプをさかのぼって探しに行くから。
サンプル1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var p3 = "hoge"; (function(){ var obj = { p1: "Hello", p2: "World" } with(obj){ console.log(p1); console.log(p2); console.log(p3); //<- 存在しないはずなんだけど…… } })(); |
p3は存在しないはずなんだけど、プロトタイプをさかのぼって外側の変数p3を呼び出しちゃう。
プロパティへの代入や、メソッドの呼び出しを間違えるとさらに悲惨。
サンプル2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
(function(){ var btn = document.getElementById('btn'); var modal = { show:function(){ alert('開くよ'); }, cloze:function(){ alert('閉じるよ') } } btn.addEventListener('click', function(){ with(modal){ show(); close(); //<- window.close()が呼ばれちゃう。 } }) })(); |
modalオブジェクトのcloseメソッドを呼び出したはずが、タイポしているせいで正しく呼ばれず、プロトタイプをさかのぼって探した結果、最終的にwindow.close()が実行されて、ブラウザウインドが閉じる orz
場合によっては、非常に見つけにくいバグの温床となることがあるので、with文を使うときは重々注意して使いましょう。