関数の関数パラメータ名を動的に取得する方法はありますか?
私の関数は次のようになっているとします:
function doSomething(param1, param2, .... paramN){
// fill an array with the parameter name and value
// some other code
}
さて、関数内からパラメータ名とその値のリストを配列に取得するにはどうすればよいでしょうか?
ベストアンサー1
次の関数は、渡された関数のパラメータ名の配列を返します。
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
function getParamNames(func) {
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null)
result = [];
return result;
}
使用例:
getParamNames(getParamNames) // returns ['func']
getParamNames(function (a,b,c,d){}) // returns ['a','b','c','d']
getParamNames(function (a,/*b,c,*/d){}) // returns ['a','d']
getParamNames(function (){}) // returns []
編集:
ES6 の発明により、この関数はデフォルトのパラメータによって失敗する可能性があります。ほとんどの場合に機能する簡単なハックを以下に示します。
var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg;
ほとんどの場合、それはいくつかの問題が起こりうるからです
function (a=4*(5/3), b) {} // returns ['a']
編集: vikasde はパラメータ値も配列で必要としていることにも気付きました。これは、arguments という名前のローカル変数で既に提供されています。
引数オブジェクトは配列ではありません。配列に似ていますが、長さ以外の配列プロパティはありません。たとえば、pop メソッドはありません。ただし、実際の配列に変換できます。
var args = Array.prototype.slice.call(arguments);
配列ジェネリックが利用可能な場合は、代わりに以下を使用できます。
var args = Array.slice(arguments);