【问题标题】:Javascript - checking for parameters before using themJavascript - 在使用参数之前检查参数
【发布时间】:2012-12-13 18:49:45
【问题描述】:

我创建了一个弹出功能,最近更改了格式:

createPopUp('My Popup',600,200);

致this method:

createPopUp({ title: 'My Popup', width: 600, height: 200 });

我只想使用存在的值,所以我目前正在这样做:

function createPopUp(config){

  if (typeof config.title != 'undefined'){
    var theTitle = title;
  } else {
    var theTitle = 'Untitled';
  }

}

但是这看起来很混乱,所以我一直在寻找一种更有效的方法来检查传入参数或设置默认值,并且非常感谢朝正确方向轻推。

【问题讨论】:

    标签: javascript function parameters


    【解决方案1】:

    您可以像这样扩展一组默认属性:

    var defaults = {
        title: 'Untitled',
        width: 100,
        height: 100
    }
    
    function createPopUp(config)
    {
        var opts = {}
    
        for (var k in defaults) {
            opts[k] = config[k] || defaults[k];
            // sometimes falsy values should be allowed to override defaults
            // in that case, use this instead:
            // opts[k] = typeof config[k] != 'undefined' ? config[k] : defaults[k]
        }
    
        // opts contains values from defaults where config doesn't have them
    }
    

    jQuery 有一个方便的$.extend() 用于此目的,但你没有这样标记你的帖子。

    【讨论】:

    • 非常感谢您,我喜欢您将默认值存储在一个对象中的方式。我确实使用 jQuery,但我想先了解它在做什么!
    • @Jack:只是出于好奇,您有什么理由使用额外的opts 对象吗? defaults[k] = config[k] || defaults[k]; 不也能正常工作吗?毕竟每次调用函数都会构造defaults对象...
    • @EliasVanOotegem 是的,你是对的;对于这个例子,我不想“污染”defaults 的内容……通常我把它放在要重用的函数之外,这就是原因。
    • 请注意,如果调用者通过例如height: 0 或title: "",此技术将不起作用。
    • @Jack 在这个特定的例子中,也许,但是下一个复制这个答案的人可能会遇到0、"" 或false 有意义的情况。 { rating: 0, extraPower: false, initialContents: "" }.
    【解决方案2】:
    var theTitle = 'Untitled';
    
    if('title' in config && config.title != null && config.title.length > 0){
        theTitle = config.title;
    }
    

    【讨论】:

    • != null 来测试你是否给它一个值。它用于消除您可能输入的情况: config = {title: null, ... };我忘了测试它是否为空 if(config.title.length > 0) ...
    • 在这种情况下,最好只写&& config.title,以检查真实值(没有空字符串、非空、非未定义、非零、非假……),因为如果config.title 是一个数字,config.title.length 会抛出错误。
    • 我同意你的看法。我将此代码仅用于定位。上述解决方案比我的要好得多:)
    【解决方案3】:

    通常,逻辑或运算符用于此:

    var theTitle = config.title || 'Untitled';
    

    基本上,右手操作数是一个表达式,它会像所有表达式一样解析为一个确定的值。它是从左到右处理的,因此如果 config.title 未定义,则字符串 'Untitled' 将是结果值。
    如果需要,您也可以链接逻辑运算符:

    var someVar = obj.val || anotherObject.val || yetAnother.foo || 'bar';
    

    或者,如果所有操作数都是对象,而你不知道存在哪一个:

    var foo = (bar || foobar || {property: 'default: none of the objects exist').property;
    

    对象引用被组合在一起,因此 JS 将首先尝试将变量(从左到右)解析为现有值,或者,最后创建一个具有所需属性的新对象字面量。访问该引用(分组逻辑或的结果),并将属性 .property 分配给 foo...我希望这至少有点清楚,如果不是:对不起。

    注意
    某些属性可能未在实例级别设置,或者可能已设置,但分配了一个虚假值。在这种情况下,逻辑 OR 是不够的,您必须使用三元或常规 if...else:

    var foo = (obj.hasOwnProperty('val') ? obj.val : 'default');//<-- uses val property, even if it's undefined, as long as it's set on the instance
    //or:
    var foo = 'default';
    if ('val' in obj)
    {//val is set, either on the instance or on its prototype-chain
        foo = obj.val
    }
    //as ternary:
    var foo = ('val' in obj ? obj.val : 'default');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多