JavaScriptで可変長引数を受け取って別の関数へ渡したい

posted in: JavaScript | 0

松山事務所の石丸です。

あるところにログ種別、フォーマット文字列、可変長のパラメータを受け取る みんなの大好きな printf のようなログ出力関数がありました。
それをそのまま使ってもいいのですが、ログ種別 “warning” を何度も間違えずに書く自信がないおじさんは、ログ種別毎に関数を用意しました。
関数名にしてしまえばIDEの支援が受けられて補完が効くし、参照も拾ってくれますよね。

いまにも動き出しそうですが、最後の引数 var_args は名前の雰囲気が可変長なだけで、ただの1つの引数でしかありません。
どうすればerrorLog関数やwarningLog関数からwriteLog関数へ可変長引数を伝えることができるのでしょうか?

そもそもどうやって可変長引数にアクセスするのか

可変長引数にアクセスするためには arguments を使います。

arguments – JavaScript | MDN

arguments は、関数へ渡された引数に対応する Array のようなオブジェクトです。

Arrayのようなオブジェクト arguments に配列のようにアクセスしてみます。

arguments には呼び出し元から渡されたパラメータがすべて入っているので、第1引数のフォーマット文字列まで取れてしまいます。
もちろん普段と同じように format や var_args でも arguments[0]、arguments[1]と同じ値が参照できます。

どうやってargumentsを渡すのか

可変長引数にアクセスする方法はわかりましたが、errorLog関数からwriteLog関数へどのように可変長引数を渡すのか。

と書いてしまいそうですが、arguments はただの配列のようなオブジェクトでしかないので、
この書き方では”error”と arguments 2つのパラメータでwriteLog関数を呼び出しただけになってしまいます。
writeLog関数の中で arguments を見てみると次のような形で渡されていました。

次のようなフラットな形で渡したいですよね。

配列のようなオブジェクトをパラメータに関数を呼び出すにはFanction.applyを使用します。
Function.prototype.apply() – JavaScript | MDN

arguments をただ引き渡すだけなら

でいいのですが、今回はログ種別も渡したい。
でもapplyは thisArgargsArray 2つのパラメータしか受け取ってくれません。

最終的には次のようになりました。

arguments の先頭にログ種別を差し込んでapplyです。
use strict だと arguments の上書きが出来ないらしいので、argumentsをsliceしてからunshiftですかね。
もっとエレガントでクールな方法があったら教えてください。ガムあげます。

追記

ES2015以降ならスプレッド構文でクールにかけるぜ!
とイケメンからアドバイスをいただきました。

良いですね!ガムあげます。

LINEで送る
Pocket