【问题标题】:Extending function parameters based on parameter type基于参数类型扩展函数参数
【发布时间】:2012-11-09 16:54:09
【问题描述】:

说明

我有一个传递参数options 的函数。此参数可以是 objectarraystring。根据参数是什么,会决定做什么。


更新:我忘了提,options 必须始终以相同结构的对象结束(换句话说,它必须始终设置默认值)。

我只想定义一次默认值,因此像你们中的一些人建议的那样使用过程 if 语句不是我的首选解决方案,但如有必要,我会使用它。

我不想这样做(如果可能的话):

function foo(options){
    switch(typeof options){
        case 'string':
            // do something etc
        break;  
        // etc
    }
}

示例

如果参数是一个对象,则扩展它以设置默认值,如下所示:

function foo(options){
    // Extend the options to apply default values
    var options = $.extend({
        bar: 'none',
        baz: []
    },options);         
}

如果参数是字符串,则将options.bar 设置为等于字符串并扩展默认值(类似这样):

function foo(options){
    // Set the bar property to equal the supplied string
    var options = {
        bar: options    
    };
    // Extend the options to apply default values
    options = $.extend({
        baz: []
    },options);         
}

如果参数是一个数组,则将options.baz 设置为等于该数组,并扩展默认值(类似这样):

function foo(options){
    // Set the baz property to equal the supplied array
    var options = {
        baz: options    
    };
    // Extend the options to apply default values
    options = $.extend({
        bar: 'none'
    },options);         
}

问题

如此有效,我希望能够提供任何格式的参数,并且该函数将从提供的内容构建相同的options 对象。如果没有提供这些值,那么它们会使用它们的默认值。

对不起,这个太不清楚了,很难解释。

附加示例

我 (jQuery) 可以演示的另一种潜在方法是查看像 animate() 这样的函数。请注意,您可以提供:

.animate( properties [, duration] [, easing] [, complete] )

.animate( properties, options )

这个额外的例子并不完全是我希望达到的,但它是正确的

【问题讨论】:

    标签: javascript jquery parameters parameter-passing sinemacula


    【解决方案1】:

    您可以使用各种 jQuery 帮助函数来确定options 的类型:

    $.isPlainObject(options)
    $.isArray(options)
    

    typeof options === "string"
    

    例如

    function foo(par) {
    
        // default values
        var options = {
            bar: 'none',
            baz: []
        };
    
        if ($.isPlainObject(par)) {
            $.extend(options, par);
        } else if ($.isArray(par)) {
            options.baz = par;
        } else if (typeof options === "string") {
            options.bar = par;
        }
    
        ...
     }
    

    如果您打算更改任何这些值,请使用 .slice() 进行数组复制,并使用 $.extend() 上的深度复制选项,这样更改不会影响提供的对象。

    更新答案

    对于这种特殊情况,答案是:

    function foo(parameter){
        var options = {
            package:    'none', // Do not load any packages by default
            packageURL: false, // Do not retrieve the package details from a URL by default
            libraries:  [] // Do not load any libraries by default
        };
        // Determine the type of parameter supplied and 
        // build the options accordingly
        if($.isArray(parameter)){
            // Set libraries option
            parameter = {
                libraries: parameter    
            };
        }else if(typeof parameter === "string"){
            // Set package option
            parameter = {
                package: parameter  
            };
        }
        // Extend the parameter object to include the default values
        $.extend(options, parameter);
    }
    

    【讨论】:

    • 感谢您的回答,但是,我知道这一点。我更想知道实现这一目标的最佳方法是什么。我不想只有 if 语句的程序列表。我只想定义一次默认值,如果options 不是对象(如果有意义的话),只需将其扩展为options 传递的任何值:-)
    • 这基本上是我试图避免做的事情,因为我认为可能有一些简洁的 jQuery 方法可以做到这一点。但是,如果这被证明是唯一的解决方案,那么我将接受它作为答案。谢谢:-)
    • 必须考虑所提供选项的类型。
    • 好的,在这种情况下,这可能是实现这一目标的唯一方法。使用开关不是更好吗? +1
    • @BenCarey 开启typeof 可以工作,但AIUI jQuery 实用功能会检测到一些“边缘情况”。
    【解决方案2】:

    您可以使用typeof 来确定所提供参数的类型。
    (typeof "abc" == "string"; typeof {a:1,b:2} == "object")

    使用它来确定要执行的代码段(Switch/case 或 if/else)

    【讨论】:

    • 再次感谢您的回答,但这并不是我真正想要的。请参阅@Alnitak 回答的评论
    • 所以您希望能够调用foo(properties, array)bar(properties, string, string, int, etc)?我认为您无法真正规避手动实施不同选项。但是,如果需要,您可以使用 arguments 数组来循环提供给函数的所有参数。
    • 绝对不是,我希望能够致电foo({foo:'test'})foo(['test'])foo('test')。请看我的更新
    • 对,你让我对你的“附加示例”感到困惑
    • 是的,很抱歉,很难解释这个问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多