松山事務所の石丸です。
JavaScriptで配列Aに対して配列Bを結合する場合、MDNのArray.prototype.pushによるとArray.prototype.pushを使って次のように書くことができます。
1
2
3
4
5
|
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];
Array.prototype.push.apply(vegetables, moreVegs);
console.log(vegetables); // ["parsnip","potato", "celery","beetroot"]
|
なぜ vegetables.push(moreVegs); ではなく、Array.prototype.push.apply なのでしょうか?
そもそもArray.prototype.pushとは
push() メソッドは、配列の末尾に 1 つ以上の要素を追加することができます。また戻り値として新しい配列の要素数を返します。
Array.pushは配列を受け取れるわけではありません。1つ以上
の要素、つまり可変長引数を取ります。
TypeScript的に型を付けてArrayクラスのpushメソッドを書くと
push(elementOrElements: any | any[]): number
ではなく
push(...elements: any[]): number
なんです。
これを勘違いしてしまうとvegetables.pushでmoreVegsを結合するようなコードを書いてしまい、
要素数が3で、3番目の要素が配列オブジェクトの vegetables が出来上がります。
1
2
3
4
5
|
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];
vegetables.push(moreVegs);
console.log(vegetables); // ["parsnip","potato", ["celery","beetroot"]]
|
Array.prototype.pushは渡された引数が何かなんて気にしていません。
渡されたものをただ後ろにくっつけるだけです。
Function.prototype.applyとは
apply() メソッドは与えられた this 参照値と、配列(もしくは配列風のオブジェクト)の形で与えられた引数を用いて関数を呼び出します。
以前 JavaScriptで可変長引数を受け取って別の関数へ渡したいの記事でも使用しましたが、可変長引数を受け取る関数
にはFunction.prototype.applyを使って、配列のようなオブジェクト
を渡すことができます。
可変長引数を受け取る関数
Array.prototype.push
配列のようなオブジェクト
moreVegs
この時のapplyの第一引数 thisArg に vegetables を渡してやれば、
1
|
Array.prototype.push.apply(vegetables, moreVegs);
|
のコードは
1
|
vegetables.push(moreVegs[0], moreVegs[1]);
|
と等価になります。
配列を結合したいなんて初学者でもよくあることだと思うのですが、
いきなり Function.prototype.apply とか出てきたらびっくりしませんかね?