JavaScriptでconcat()は配列のコピーを行なうために使う


JavaScriptでconcatはもう使うべきではないのかもしれない (Kanasansoft Web Lab.)に対して、いくつか気になったので突っ込む。
私は親戚のActionScriptしか知らないから、もしかしたら間違ってるかもね!

push()が追加、concat()がコピー

push()とconcat()は似たような動作って書かれているけど、用途が全然違う。
push()が配列の要素に追加、concat()が配列のコピーをするときに使う。


例えばaryの値を変更せずに、要素を追加したい場合は、

var ary = [0,1,2];
var result = ary.concat();
result.push(3);
result.push(4);
result.push(5);

//ary = [0,1,2]
//result = [0,1,2,3,4,5]

のように書く。


追加するタイミングが同じなら、ary.concat(3,4,5)と書いても特に問題は無い。
追加するタイミングが同じで無いなら、push()を使うべきだろう。

二次元配列でconcat()を使う場合は要注意!

元記事読んで気がついたけど、concat()の仕様がキモイ。
concat()は引数の型が、配列でも、それ以外でも空気を読んで追加してくれる。
引数が配列の場合は、その要素を連結する。


しかし、多次元配列を扱おうとした場合、逆に問題が出てくる。

var a = [[1,2],[3,4],[5,6]]
var b = a.concat([7,8],[9,10])
//b = [[1,2],[3,4],[5,6],7,8,9,10]


このような多次元配列を使う場合は、push()に頼ろう。

var a = [[1,2],[3,4],[5,6]]
var b = a.concat();
b.push([7,8],[9,10]);
//b = [[1,2],[3,4],[5,6],[7,8],[9,10]]

push()なら、引数の型が配列であろうと、一つの要素として扱うので問題ない。

push.apply()

配列の要素を展開して引数に入れたい場合、apply()というメソッドを使用する。
このapply()、Functionのメソッド。


例えば

var a = [1,2,3];
var b = [4,5,6];
var c = a.concat();
c.push(b[0],b[1],b[2]);
//c=[1,2,3,4,5]


の様に、bの要素一ずつ入れるのはめんどくさい。
で、apply()を使うと以下の様に書ける。

var a = [1,2,3];
var b = [4,5,6];
var c = a.concat();
Array.prototype.push.apply(c,b);
//c=[1,2,3,4,5]


元記事を参考に書いた。これでbをわざわざ展開せずにすんだ。


ところで「クラス名.prototype.メソッド.apply(引数);」ていう書き方はJavaScriptではよくあるのかな?
私だったら、

var a = [1,2,3];
var b = [4,5,6];
var c = a.concat();
c.push.apply(c,b);
//c=[1,2,3,4,5]

の様に書くけど。これでも問題ないよね?
短いという点でこっちの方が好き。