せかいろぐ

ほぼ自分用備忘録

JavaScriptのwith文に要注意

JavaScriptのwith文について。


JavaScriptにはwith文というものがあります。参考リンク
オブジェクトの参照の反復をスッキリさせることができて便利な構文です。

例えば、「DOMで画像のtransformプロパティを編集したい!」なんて時。

document.getElementById("image").style.transform = "rotate(90deg)";
document.getElementById("image").style.OTransform = "rotate(90deg)";
document.getElementById("image").style.msTransform = "rotate(90deg)";
document.getElementById("image").style.MozTransform = "rotate(90deg)";
document.getElementById("image").style.WebkitTransform = "rotate(90deg)";


ベンダープレフィックスを考慮するとこういうとんでもないコトになります。
そこでwith文を使うと・・・

with(document.getElementById("image").style){
	transform = "rotate(90deg)";
	OTransform = "rotate(90deg)";
	msTransform = "rotate(90deg)";
	MozTransform = "rotate(90deg)";
	WebkitTransform = "rotate(90deg)";
}


(これは極端な例ですが)とてもシンプルになります。

ボクなんか好きで、1文字でも削るためによく使うんですが、参考リンク先にもあるように、欠点(パフォーマンスの低下、曖昧性 など)が多く、利用は非推奨のようです。

思わぬバグを生む原因にもなります。例えばログを変数 log なんかに入れておいて、with(Math){ ... }の中で参照するとします。

var log = "hogehoge";
with(Math){
	...
	...
	console.log(log);
}

すると出力は以下のようになります。

function log() { [native code] }


!?

withの中では、指定されたオブジェクトのメンバーが最優先で参照されるようで、こういうコトになります。ボクはこれで大変苦労したので、便利なwith文ですが使用時は十分注意しましょう。。。


MDNによると、

推奨される代替案は、参照したいプロパティを持つオブジェクトを一時変数に代入することです。


とのことで、これに従うと、一番最初に示したコードは、

var style = document.getElementById("image").style;

style.transform = "rotate(90deg)";
style.OTransform = "rotate(90deg)";
style.msTransform = "rotate(90deg)";
style.MozTransform = "rotate(90deg)";
style.WebkitTransform = "rotate(90deg)";


と書けます。十分シンプル。