是否有一种方法可以动态地获取函数的函数参数名?

假设我的函数是这样的

function doSomething(param1, param2, .... paramN){
   // fill an array with the parameter name and value
   // some other code 
}

现在,我如何从函数内部获得参数名称及其值的列表到数组中?


当前回答

我通常是怎么做的:

function name(arg1, arg2){
    var args = arguments; // array: [arg1, arg2]
    var objecArgOne = args[0].one;
}
name({one: "1", two: "2"}, "string");

你甚至可以通过函数名引用参数,比如:

name.arguments;

希望这能有所帮助!

其他回答

function getArgs(args) {
    var argsObj = {};

    var argList = /\(([^)]*)/.exec(args.callee)[1];
    var argCnt = 0;
    var tokens;

    while (tokens = /\s*([^,]+)/g.exec(argList)) {
        argsObj[tokens[1]] = args[argCnt++];
    }

    return argsObj;
}

你可以使用"arguments"属性访问传递给函数的参数值。

    function doSomething()
    {
        var args = doSomething.arguments;
        var numArgs = args.length;
        for(var i = 0 ; i < numArgs ; i++)
        {
            console.log("arg " + (i+1) + " = " + args[i]);  
                    //console.log works with firefox + firebug
                    // you can use an alert to check in other browsers
        }
    }

    doSomething(1, '2', {A:2}, [1,2,3]);    

我通常是怎么做的:

function name(arg1, arg2){
    var args = arguments; // array: [arg1, arg2]
    var objecArgOne = args[0].one;
}
name({one: "1", two: "2"}, "string");

你甚至可以通过函数名引用参数,比如:

name.arguments;

希望这能有所帮助!

这是我的解决方案——它适用于命名函数和未命名函数,异步和非异步函数,异步和非异步lambdas,以及带和不带paren的lambdas。

const STRIP_COMMENTS = /((\/\/.*$)|(\/\*.*\*\/))/mg;
const STRIP_KEYWORDS = /(\s*async\s*|\s*function\s*)+/;
const ARGUMENT_NAMES = /\(([^)]+)\)\s*=>|([a-zA-Z_$]+)\s*=>|[a-zA-Z_$]+\(([^)]+)\)|\(([^)]+)\)/;
const ARGUMENT_SPLIT = /[ ,\n\r\t]+/;
function getParamNames(func) {
    const fnStr = func.toString()
        .replace(STRIP_COMMENTS, "")
        .replace(STRIP_KEYWORDS, "")
        .trim();
    const matches = ARGUMENT_NAMES.exec(fnStr);
    var match;
    if (matches) {
        for (var i = 1; i < matches.length; i++) {
            if (matches[i]) {
                match = matches[i];
                break;
            } 
        }
    }
    if (match === undefined) {
        return [];
    }
    return match.split(ARGUMENT_SPLIT).filter(part => part !== "");
}

从@jack-allan中得到答案,我稍微修改了函数,以允许ES6的默认属性,如:

function( a, b = 1, c ){};

仍然返回['a', 'b']

/**
 * Get the keys of the paramaters of a function.
 *
 * @param {function} method  Function to get parameter keys for
 * @return {array}
 */
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /(?:^|,)\s*([^\s,=]+)/g;
function getFunctionParameters ( func ) {
    var fnStr = func.toString().replace(STRIP_COMMENTS, '');
    var argsList = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')'));
    var result = argsList.match( ARGUMENT_NAMES );

    if(result === null) {
        return [];
    }
    else {
        var stripped = [];
        for ( var i = 0; i < result.length; i++  ) {
            stripped.push( result[i].replace(/[\s,]/g, '') );
        }
        return stripped;
    }
}