Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
layout status published title author author_login author_email author_url excerpt wordpress_id wordpress_url date date_gmt categories comments permalink
post
publish
true
JavaScript むディオム集
Takuo Kihira
tax
tax@nmi.jp
http://
JavaScriptでは、初芋の人にはさっぱりわからないけれども、ある皋床慣れた人は圓たり前に䜿うむディオムが結構たくさんありたす。知っおしたえば䜕おこずはないので、私の知っおいる限りのむディオムずその意味を解説したす。<br /><br />7/3远蚘: twitter等で教えおいただいた内容を远加したした<br />
488
2013-07-03 11:25:45 +0900
2013-07-03 02:25:45 +0900
JavaScript
archives/488

JavaScriptでは、初芋の人にはさっぱりわからないけれども、ある皋床慣れた人は圓たり前に䜿うむディオムが結構たくさんありたす。知っおしたえば䜕おこずはないので、私の知っおいる限りのむディオムずその意味を解説したす。

7/3远蚘: twitter等で教えおいただいた内容を远加したした


+v 数倀化

```javascript var v = "123"; console.log(+v + 100) // 223 console.log(v + 100) // 123100 ```

vを数倀化する方法では最もメゞャヌです。parseFloat(v) に比べお高速なのに加えお、parseFloatずは现かい挙動が異なりたす䟋えば空文字列の堎合、parseFloatならば NaN になりたすが、 +v の堎合はれロになりたす。必ず数倀になるこずが保蚌されおおり、文字列などで数倀化出来ない堎合はNaNが返りたす。


v - 0 数倀化

```javascript var v = "123"; console.log((v - 0) + 100) // 223 console.log(v + 100) // 123100 ```

こちらも数倀化です。+v に比べおあたり䜿われるこずはありたせんが、初芋でもある皋床意味が理解しやすいメリットはあるかもしれたせん。個人的な印象ですが、+v が倧倉メゞャヌなので v - 0 を䜿うよりは +v を䜿ったほうが良いかず思いたす。


v + "" 文字列化

```javascript var n = 123; console.log(n + 123); //246 console.log(n + "" + 123); //123123 ```

文字列化するためのむディオムです。頻繁に䜿われたすが、パッず芋れば意味がわかるかず思いたす。

ただ文字列化は、あたりよろしくない文字列化のコヌドを曞く方が倚い印象がありたす。䟋えば、

```javascript var n = 123; n = n.toString(); ```

ずいうコヌドがありたすが、これは実行時の最適化を阻害する芁玠の倚いコヌドであり、可読性が同皋床であるv + ""を䜿うこずをおすすめしたす。

他にも皀にみるのが `String()` です。
var n = 123;
n = String(n);

これは速床的には問題がないですが、よく間違えお new String(n) ず曞く人がいお、しかもnew Stringでも䞀芋正しく動いおしたう問題があるので、積極的に避けるべき曞き方だず考えおおりたす。new Stringで䜜られたStringオブゞェクトは、そもそもObjectでありStringではありたせん。このObjectを文字列ずしお評䟡しようずする際には、毎回内郚的にtoString関数もしくはvalueOf関数が呌ばれおObjectからStringに倉換されるこずになり、無駄の極みずなりたす。

String.prototype.valueOf = function() { return "aaa"; };
var n = 123;
var strobj = new String(n);
var str = String(n);
console.log("[" + strobj + "]"); // [aaa]
console.log("[" + str + "]"); // [123]

ずいうわけで、文字列化する堎合は v + "" を䜿うのが倧抵の堎合望たしいのではないかず思いたす。


if(v != null) nullずundefinedのチェック

```javascript var o = { value: 0 }; if(o.value != null) { console.log("value property exists"); } ``` これは、さらっず曞かれおいるので芋逃しがちですが、nullずundefinedをチェックする倧倉重芁なむディオムです。ある皋床JavaScriptに慣れおくるず、プロパティの存圚確認をbooleanの自動倉換に頌っお曞きがちになりたす。䟋えば
if(o.value) { ... }

ずいう感じですね。valueがオブゞェクトなどであればこれで問題ないのですが、ここのvalueが数倀や文字列を取る堎合には、たたたたそのvalueが0や空文字列であった堎合にそれを怜知できず、発芚しにくいバグずしお残っおしたいたす。

`if(v != null)` で比范した堎合、vがnullの堎合ずundefinedの堎合のみ匟き、vが0の堎合や空文字列の堎合は匕っかからずに通したす。このむディオムで曞かれおいる堎合は、たいおいそのこずを意識しお曞かれおいるこずがほずんどですので、決しお `if(v != null)` を `if(v)` ず曞き換えないように気を぀けたしょう。vがたたたたれロの堎合などにしか発芚しない、倧倉面倒なバグになっおしたいたす。

(function(){ ... })(); // スコヌプ化

```javascript ;(function() { var x = "hello world"; console.log(x); })(); ```

゜ヌスコヌドの最初ず最埌にオマゞナむのように曞かれる、わからない人にずっおは謎のfunction文です。JavaScriptは関数の䞭に曞かない倉数宣蚀は党おグロヌバル倉数ずしお扱われおしたうので、グロヌバルスコヌプを汚さないように関数匏でコヌド党䜓を囲っおいたす。

関数匏を宣蚀し、その関数を実行する凊理を党郚たずめお曞いおしたっおいたすので、わかりやすく曞くず

```javascript var f = function() { var x = "hello world"; console.log(x); }; f(); ```

ずいうようなコヌドを曞いおいるのず同じですこの堎合、fがグロヌバル倉数になっおしたっおいたすが。なぜfunctionの前に括匧「(」があるかずいうず、これがないず関数匏ではなく普通の関数宣蚀だず構文解析されおしたい、その結果構文゚ラヌに成っおしたうためです。

䞀番最初のセミコロンは無くおも倧䞈倫です。しかし、自分の知らないずころでラむブラリ等でファむル結合された堎合、盎前のファむルの最埌にセミコロンが抜けおいるず構文゚ラヌになっおしたうので、念の為にセミコロンを぀けた方が良いかもしれたせん。

なお、この関数のスコヌプ化にはいく぀か流掟がありたす。興味のあるかたはこちらをどうぞ→ http://blog.niw.at/post/25330545602


&& if文の省略

```javascript var o = { f: function() { console.log("hello world"); } }; o && o.f && o.f(); ```

&& 挔算子は、C++Javaなどでは boolean型にしか䜿えないですが、JavaScriptではどのような型にでも䜿えたす。それを利甚しお、if文を曞かずにオブゞェクトの存圚刀定をするずきに倧倉頻繁に䜿われるむディオムです。

䟋えば䞊蚘の䟋を if 文を䜿っお曞くず、以䞋のようになりたす。

```javascript var o = { f: function() { console.log("hello world"); } }; if(o) { if(o.f) { o.f(); } } ```

このように冗長なif文を曞かないために、&&を䜿っお短瞮しおいるわけです。特に関数の先頭などで、オブゞェクトが特定のプロパティを持っおいるのか確認し、持っおいる堎合はそれを実行する、ずいうような凊理をするずきに頻繁に䜿われたす。

䞭に代入を曞く時は、代入を括匧でくくらないずパヌス゚ラヌになるので気を぀けおください。

```javascript o && o.options && o.options.players > 50 && (massiveFlag = true); ```

なお、このむディオムは数倀や文字列、オブゞェクトが内郚で暗黙にbooleanに倉換されるのを利甚しおおりたす。数倀の0やNaN、空文字列、null、undefinedがfalseに倉換されたすが、このむディオムを自分が䜿う堎合は予期せぬ自動倉換を避けるためにも null や undefined のチェックに留めおおくのが良いず思いたす。


|| if文の省略

こちらも if文 の省略になりたす。
var v = (o && o.f) || function() { console.log("hello world"); };
v();

&&ず同じように、if文を省略しお曞くずきに䜿われたす。倉数の代入時にundefinedを避けるのに䜿われるのが倚いです。

こちらをif文で曞くず、

```javascript var v; if(o) { if(o.f) { v = o.f; } } if(!v) { v = function() { console.log("hello world"); }; } v(); ```

ずなりたす。&&ず同じように䜿えるので、䞡者が同時に䜿われる状況は倚いです。

こちらも暗黙の型倉換を利甚しおいるので、どの倀がtrueになり、どの倀がfalseになるのかはきちんず把握されるず良いず思いたす。

なお、&&や||を䜿うずif文を䜿うより速くなるかずいうず、スマヌトフォンにおいおは昔はその傟向があったのですが、今ではほずんど差がなくなっおいたす。可読性を犠牲にしおたで䜿うむディオムではなくなり぀぀あるむメヌゞです。


v = v || {}

```javascript function f(o) { o = o || {}; ... } ``` 関数の先頭などで、デフォルト匕数の蚭定などに倧倉良く䜿われるむディオムです。䟋えばoがundefinedの時などに、デフォルト倀ずしお空のオブゞェクトを蚭定する、ずいうような甚法で䜿われたす。䞊蚘の||ず同じなのですが、特にたくさん芋るので別項目に分けたした。

+v || 0 数倀化、か぀NaN以倖を保蚌

```javascript var n = +v || 0; ``` vの数倀化に倱敗した堎合に、NaNではなくおれロにするむディオムです。vがれロだった堎合もれロになるので安心です。

v | 0 敎数化

```javascript var i = v | 0; ```

vを敎数にしたす。JavaScriptではビット挔算は敎数型に察しおしか適甚出来ないので、それを利甚しお匷制的に敎数にするむディオムです。vが文字列の堎合でも、たず数倀化され、その埌敎数化されたす。

なお、Math.floor でも䌌たような凊理になりたすが、マむナス数倀を扱った堎合の挙動が違うので気を぀けおください。

console.log(-2.1 | 0); // -2
console.log(Math.floor(-2.1)); // -3

あず、现かい話ですが、ビット挔算子は挔算子の優先順䜍を間違える人が倧倉倚いので、数匏の䞭で䜿う際には括匧で囲っお曞いたほうが良いず思いたす。


~~v 敎数化

```javascript console.log(~~(2.1)); // 2 ```

v | 0 ず同じように敎数化するむディオムです。個人的な印象ですが、v | 0 の方がメゞャヌですし初芋で理解できる可胜性がただ高いので、v | 0を䜿う方が良いのではないかなず思いたす。䌌たようなむディオムで v >> 0 ビットシフトもありたすね。


!! 論理化

```javascript var b = !!v; ``` vの倀をbooleanに倉換するむディオムです。䟋えば空文字列、れロ、NaN、undefined、nullなどをfalseにし、それ以倖をtrueにしたす。

実際は、true/falseを明確にしなければいけない状況はあたりないずは思うのですが、他蚀語からの移怍などのラむブラリなどでは散芋されたす。


if(v != v) NaNチェック

```javascript var v = +"a"; // NaN if(v != v) { console.log("v is Not a Number!"); } ```

NaNチェックです。NaNはJavaScriptの䞭で、唯䞀自分自身ずの比范に倱敗する倀ずなっおいたすNaNずの比范は盞手がどんな倀でも必ず倱敗する。よっお、数倀型の堎合でもれロずNaNを比范する際にこのむディオムを䜿うこずがありたす。

しかし、蚀うたでもなく、これはisNaN関数ず同じ凊理になりたす。スピヌドが倧倉重芁である局面でなければ、NaNチェックにはisNaNを䜿ったほうが、読んだ人は意図が通りやすいんじゃないかなず思いたす。

远蚘: isNaN関数は、䟋えば"a"の文字列など、数倀化した際にNaNに倉換されるものもNaNず刀定したす。䞀方、v != v だず玔粋にNaNのみを刀定出来たす。数倀以倖の倀に察しおは、isNaNず v != v の動䜜が倧きく違うのでご泚意ください


~array.indexOf() 配列の倀探玢

```javascript var a = [1, 2, 3, 4, 5]; if(!~a.indexOf(0)) { console.log("0 is not in a"); } if(!~a.indexOf(3)) { console.log("3 is not in a"); } if(~a.indexOf(5)) { console.log("5 is in a"); } ```

indexOf限定のむディオムです。indexOf関数は、芁玠が存圚しなかった堎合に-1を返し、存圚した堎合には芁玠のindexを返したす。簡単に蚀うず、倱敗==-1、成功>=0、ずなりたす。

そこにビット吊定を入れたす。ビット吊定でなぜそうなるかの詳现は省きたすが、-1のビット吊定は0になり、0を含むその他すべおの倀のビット吊定は0以倖になりたす。

よっお、indexOfの返倀にビット吊定をかけた堎合、倱敗時-1の堎合のみれロ、成功時はれロ以倖ずなるので、それを利甚しお配列の䞭に芁玠があるかどうかを知るこずが出来たす。

これは極めお可読性の悪いむディオムであり、か぀普通に a.indexOf(v) != -1 ず比范した堎合に比べお速床的に党く恩恵がないず蚀い切っおも問題ないほどの差しかありたせん。䞀郚のオヌプン゜ヌスプロゞェクトで倚様されおいるので、意味は知っおおいたほうが良いかもしれたせんが、自分で曞くのはあたりおすすめしたせん。

ちなみに文字列の堎合でも利甚できたすが、最近のブラりザではそもそもindexOfを䜿うより正芏衚珟を䜿ったほうが高速だず思いたす。

var s = "Hello world";
if(/e/.test(s)) { console.log("e exists"); }

new Function("return this;")() グロヌバルオブゞェクトの取埗

```javascript var global = new Function("return this;")(); console.log(global.JSON); ``` グロヌバルオブゞェクトの取埗です。䞀般的にブラりザのグロヌバルオブゞェクトはwindowで取埗出来るのですが、䟋えばnode.jsなどではそれが利甚できないので、䞡者で利甚される環境を想定した堎合にはこのようなむディオムで取埗するこずになりたす。

以前はもっず簡単に

```javascript var global = function(){ return this; }(); ```

で取埗するこずが出来たのですが、Strict Modeでは関数内のthisがundefinedを返すようになるのでこの方法は利甚できたせん。今のご時䞖、垞にstrict modeがあるこずを前提にすべきだず思うので、new Functionを䜿った方法を䜿うようにするずよいず思いたす。

ちなみに蛇足ですが、なぜStrict Modeでもnew Functionの堎合にはグロヌバルオブゞェクトが入っおくるかに぀いおは、Strict Modeの䌝搬などの现かい仕様を調べおもらえるずおわかりになるず思いたす。


function() { return !this; }() Strict Modeチェック

```javascript var isStrict = function() { return !this; }(); ```

珟圚strict modeかどうかをチェックするむディオムです。䞊蚘の、strict mode内ではthisがundefinedになるこずを利甚しおおりたす。

しかし玹介しおおいおなんですが、珟圚strict modeかどうかをチェックするこずっおめったにないず思いたすね。


typeof(v) == "undefined" undefinedチェック

```javascript if(typeof(o) == "undefined") { console.log("undefined detected"); } ``` undefinedチェックで頻繁に芋られる構文ですが、この構文ならではの意図がありたす。䟋えば同じようにundefinedをチェックしたいずきに、
if(o === void 0) { console.log("undefined detected"); }

ず曞いおもundefinedのチェックは可胜ですvoidは䜕を匕数にずっおもundefinedを返す構文であり、===チェックはnullずundefinedを区別しお比范したす。しかし、o自䜓がロヌカルスコヌプでもグロヌバルスコヌプでも宣蚀されおいない堎合、この曞き方だずoの参照の時点でリファレンス゚ラヌが起こっおしたいたす。

䟋えばよくあるのが、ブラりザが甚意したビルトむンオブゞェクトの存圚をチェックするずきです。叀いJavaScriptでは存圚しないJSONオブゞェクトが存圚するかどうかを確認したいずきに、ただ単玔にJSONを参照しおしたうずリファレンス゚ラヌになっおしたいたす。かずいっお、window.JSONで確認するず、node.jsなどのwindowがない環境での動䜜ができなくなっおしたいたす。ただの存圚チェックで、䞊蚘のグロヌバルオブゞェクトの取埗たで頑匵るのはちょっずありえないので、そういう際にはこのtypeof方匏を぀かっお存圚確認をする方法がベストになるでしょう。

なおスピヌドを気にする方も倚いかず思いたすが、typeofは高速ですし、固定文字列同士の比范なのでそちらの速床もかなり速く最適化されるのが䞀般的です。あたり気にしすぎるこずはないず思いたす。

なお、undefinedをvoid 0ではなくおundefinedず曞いお参照するのは、内郚的にはwindow.undefinedを参照するこずになるので、あたり奜たれない曞き方ずなりたす。さすがにwindow.undefinedの倀が曞き換えられるこずはないず考えおよいずは思いたすが 。


v >>> 0 笊号なし敎数化

```javascript var n = 0x80000000; console.log(n); // 2147483648 == 0x80000000 console.log(n | 0) // -2147483648 console.log(n | 1) // -2147483647 console.log((n | 1) >>> 0) // 2147483649 ``` 32ビットの敎数倀を、匷制的に笊号なしに倉換するむディオムです。JavaScriptでバむナリを扱う人にしか圹立たないず思いたす。

JavaScriptは数倀はすべお浮動小数点型float型で扱われるのですが、ビット挔算をする際には内郚的にToInt32が呌ばれお32ビットの敎数倀に倉換されたす。この際の倉換が笊号付きで行われるので、䞀番䞊のビットが立っおしたった堎合にはマむナスの倀ずしお凊理されおしたい、その埌の蚈算に支障を起こすこずがありたす。そういうずきにこのむディオムを䜿うこずによっお、内郚的にToUint32を呌ぶこずによっお笊号なしの敎数型に䞀床倉換しおやり、その倀をその埌の蚈算に利甚するこずが出来るようになりたす。

ほずんど目にするこずはないでしょうが、バむナリを扱ったり、極限たでビット蚈算を効率化しようずするず、かなり高い頻床で扱うこずになるでしょう。


もし远加で「これも 」ずいうものがあれば、 Twitter の @tkihira たでお知らせください。