如何获取JavaScript函数中缺少的参数的名称?

如何获取JavaScript函数中缺少的参数的名称?,javascript,function,Javascript,Function,在JavaScript中,我试图获取函数中未定义的所有参数的名称。如果此函数中的任何参数未定义,则我希望该函数抛出一个错误,列出缺少的参数的名称 我已经找到了这个问题的解决方案,但它要求每个参数都有一个单独的条件语句,我想知道是否有更简洁的方法来获取未定义参数的列表: function fnDrawPrism(length, width, height){ //If any of these parameters are undefined, throw an error tha

在JavaScript中,我试图获取函数中未定义的所有参数的名称。如果此函数中的任何参数未定义,则我希望该函数抛出一个错误,列出缺少的参数的名称

我已经找到了这个问题的解决方案,但它要求每个参数都有一个单独的条件语句,我想知道是否有更简洁的方法来获取未定义参数的列表:

function fnDrawPrism(length, width, height){
        //If any of these parameters are undefined, throw an error that lists the missing parameters.
        return length*width*height;
}

您可以将它们保存在对象中,并通过其键进行迭代:

var toReturn = "";
if((typeof length == "undefined") || (length == "undefined")){
    toReturn += "length is not defined!";
}
if((typeof width == "undefined") || (width == "undefined")){
    toReturn += "width is not defined!";
}
if((typeof height == "undefined") || (height == "undefined")){
    toReturn += "height is not defined!";
}
if(toReturn != ""){
    throw new Error(toReturn); //if any parameters are missing, then list the names of all missing parameters
}
为不想多想的人编辑


这应该在函数中完成,javascript中没有简单的方法获取函数的第一个、第二个或第n个参数的名称。也许可以检查函数的字符串版本并将其解析出来,但我怀疑您是否愿意这样做

您可以在数组或对象中构建自己的名称列表,然后使用
参数
对象迭代参数,检查每个参数的有效性,然后使用自己的名称数组获取第n个参数的名称(如果有错误)

例如,您可以这样检查每个参数:

function fnDrawPrism(length, width, height){
    var params = {
        length: length,
        height: height,
        width: width
    }

    for(var field in Object.keys(params))
    {
        if(params[field] === undefined)
        {/* do what you want */}
    }
    ...
}
函数fnDrawPrism(长度、宽度、高度){
//如果这些参数中有任何一个未定义,则抛出一个列出缺少的参数的错误。
变量argNames=[“长度”、“宽度”、“高度”];
if(arguments.length
在此进行工作演示:



如果您想重新构造代码并传递一个带有键/值作为参数的对象,那么迭代它们并从传递的对象键中获取arg名称就容易得多。但是,我假设您在问一个关于具有多个参数的普通函数调用的问题,所以这就是我在上面提供的答案。

您可以使用以下方法提取名称:

对于您的功能:

function get_args(fn) {
    return fn.toString().match(/\((.*)\)/)[1].split(", ")
}
function fnDrawPrism(length, width, height){
    var msg = [],
        argNames = fnDrawPrism.toString().match(/\(([^)]*)\)/)[1].split(/\s*,\s*/);
    for (var i = 0; i < fnDrawPrism.length; i++)  // for each declared argument
      if (typeof arguments[i] === "undefined")
          msg.push(argNames[i]);
    if (msg.length > 0)
        throw new Error("fnDrawPrism missing argument(s): " + msg.join(", "));

    // ACTUAL function body goes here
}

下面是一个独立的验证函数,您可以从任何函数中使用该函数,使用匈牙利符号检查传递的参数的存在性和类型正确性:

function fnDrawPrism(length, width, height){
    return length*width*height;
}
get_args(fnDrawPrism) // [ 'length', 'width', 'height' ]
函数fnDrawPrism(长度、宽度、角度){
//如果这些参数中有任何一个未定义,则抛出一个列出缺少的参数的错误。
//您可以剪切并通过声明行来填写90%的验证调用:
验证(fnDrawPrism,长度,numWidth,在右侧);
返回长度*numWidth*intHeight;
}
//这是剪切和粘贴到文件的某个地方,编辑以添加更多类型或更严格的检查
函数验证(args){
var fn=args,实际值=[].slice.call(参数,1),
hung={int:“Number”,num:“Number”,str:“String”,arr:“Array”,
obj:“对象”,inp:“HTMLInputElement”,dt:“日期”,bln:“布尔”,
rx:“RegExp”,frm:“HTMLFormElement”,doc:“HTMLDocument”},
名称=字符串(fn)。拆分(/\s*\)\s*/)[0]。拆分(/\s*\(\s*/)[1]。拆分(/\s*\,\s*/),
mx=names.length,i=0;
如果(!fn.name)
fn.name=String(fn).split(/\s*(/)[0]。split(/\s+/)[1]| |“anon”;
对于(i;i
您不能只将“参数”传递给验证器的原因是,严格模式对arguments对象施加了太多的限制,无法可靠地使用它。Ecma6将有一种一次性传递所有参数的方法,但这种方法只适用于未来的浏览器,而长期的方法适用于当时、现在和永远的浏览器


编辑:根据注释更新验证例程,使其更强大,将文档、输入、表单、数组、regexp、日期和对象添加到匈牙利符号验证例程中,该例程现在也可以跨窗口对象工作。

在我看来,更通用的“缺少参数2”类型异常是足够的-看到这样一个异常的开发人员会去检查参数2实际上是什么。此外,最好谈论“未定义”而不是“缺少”,因为有人可能会说
fnDrawPrism(未定义,1,2);
在这种情况下,第一个参数实际上不是“缺少”

无论如何,如果您决定显示名称,下面是我的想法,使用
.toString()
和函数上的正则表达式来获取参数名称:

function fnDrawPrism(length, numWidth, intHeight){
    //If any of these parameters are undefined, throw an error that lists the missing parameters.
    // you can cut-and-past the declaration line to fill out 90% of the validation call:
    validate(fnDrawPrism, length, numWidth, intHeight); 

    return length * numWidth * intHeight;
}

// this is cut-and-pasted into a file somewhere, edit to add more types or stricter checking
function validate(args){
    var fn = args, actuals = [].slice.call(arguments, 1),
        hung = {int: "Number", num: "Number", str: "String", arr: "Array",
        obj: "Object", inp: "HTMLInputElement", dt: "Date", bln: "Boolean",
        rx: "RegExp", frm: "HTMLFormElement", doc: "HTMLDocument"},
        names = String(fn).split(/\s*\)\s*/)[0].split(/\s*\(\s*/)[1].split(/\s*\,\s*/),
        mx = names.length, i = 0;
    if(!fn.name)
        fn.name = String(fn).split(/\s*(/)[0].split(/\s+/)[1] || 'anon';
    for(i; i < mx; i++){
        if(actuals[i] === undefined)
            throw new TypeError("missing arg #" + i + " in " + fn.name + " - " + names[i]);
        var hint = hung[names[i].split(/[A-Z]/)[0]],
            got = toString.call(actuals[i]).split(/\W/)[2];
        if(hint && got !== hint)
            throw new TypeError("Wrong type in argument #" + i + " of " + fn.name + " - " + names[i] + ". Got: " + got + ", Expected: " + hint);
}

//try it out:
fnDrawPrism(1);       //! missing arg #1 in fnDrawPrism - numWidth
fnDrawPrism(1,4);     //! missing arg #2 in fnDrawPrism - intHeight
fnDrawPrism(1,2,3);   // ok
fnDrawPrism(1,"2",3); //! Wrong type in argument #1 of fnDrawPrism - numWidth. Got: string, Expected: number
函数fnDrawPrism(长度、宽度、高度){
var msg=[],
argNames=fnDrawPrism.toString().match(/\([^)]*)\/)[1]。拆分(/\s*,\s*/);
for(var i=0;i0)
抛出新错误(“缺少参数:”+msg.join(“,”);
//实际函数体在这里
}
假设您希望在所有函数中执行类似的验证,您可以将其拉入单独的函数中:

function get_args(fn) {
    return fn.toString().match(/\((.*)\)/)[1].split(", ")
}
function fnDrawPrism(length, width, height){
    var msg = [],
        argNames = fnDrawPrism.toString().match(/\(([^)]*)\)/)[1].split(/\s*,\s*/);
    for (var i = 0; i < fnDrawPrism.length; i++)  // for each declared argument
      if (typeof arguments[i] === "undefined")
          msg.push(argNames[i]);
    if (msg.length > 0)
        throw new Error("fnDrawPrism missing argument(s): " + msg.join(", "));

    // ACTUAL function body goes here
}
函数
function validateParams(names, vals) {
    var missing = [];
    for (var i=0; i<names.length; i++) {
        if (vals[i] === undefined) missing.push(names[i]);
    }
    if (missing.length > 0) throw "Missing arguments: " + missing.join(', ');
}

function fnDrawPrism(length, width, height){
    validateParams(['length', 'width', 'height'], [length, width, height]);
    return length * width * height;
}