如何“;默认“;JavaScript中的布尔属性

How do I "default" a boolean property in JavaScript?

本文关键字:布尔 属性 JavaScript 默认 如何      更新时间:2023-09-26

在JavaScript中,我经常使用||运算符来获取某些属性的值,或者默认值。例如:

var dens = mapping.defaultElementNamespaceURI||mapping.dens||'';

如果mapping具有defaultElementNamespaceURI,则将使用它,否则查找dens或默认使用空字符串。

但是,如果我的属性是布尔值,它就不起作用:

var dom = mapping.allowDom || mapping.dom || true;

即使mapping.domfalse,也返回true

我想知道,默认布尔属性的最佳语法(简洁但可读)是什么?从某种意义上说,如果定义了属性,则使用其值,否则将使用某个提供的默认值。当然,我可以为此编写一个函数,但也许还有像a || b || c这样优雅的函数?

代码示例:

var a = {};
$('#result').text(a.boo||a.b||true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id="result"></pre>


更新

似乎没有"语法上甜蜜"的方法来做到这一点,所以我求助于编写一个函数:

var defaultValue = function()
{
    var args = arguments;
    if (args.length === 0)
    {
        return undefined;
    }
    else
    {
        var defaultValue = args[args.length - 1];
        var typeOfDefaultValue = typeof defaultValue;
        for (var index = 0; index < args.length - 1; index++)
        {
            var candidateValue = args[index];
            if (typeof candidateValue === typeOfDefaultValue)
            {
                return candidateValue;
            }
        }
        return defaultValue;
    }
}

将最后一个参数视为默认值。返回与默认值具有相同类型的第一个参数。

最接近优雅的东西是:

var dom = mapping.allowDom ? mapping.allowDom : mapping.dom ? mapping.dom : true;

正如所指出的,这只是一次在场检查。您可以执行以下任一操作来接受false值:

var dom = mapping.allowDom != null ? mapping.allowDom : mapping.dom != null ? mapping.dom : true;

var dom = 'allowDom' in mapping ? mapping.allowDom : 'dom' in mapping ? mapping.dom : true;

完整性更新:如果您有一个可比较的变量值列表,那么更新中的函数是理想的。但是,如果我们唯一比较的是上面提到的2个(并且我们控制着设置/验证mapping.thing),我的代码将如下所示。(我也不知道你以后是如何使用dom的。)

var dom = mapping.allowDom || mapping.dom;
dom = dom === undefined ? true : dom;

任何超过2个元素的东西,我可能会选择你的方法。

a.x || b

如果a.x是"false"(未定义的空字符串、0和其他一些值),将返回b的值。

如果您需要显示某些内容,除非字段在对象中,即使字段的值为false,也必须明确表示。

'x' in a ? a.x : b

如果将a.x显式设置为undefined,则该表达式将返回'undefined',而不是b.

这比公认的答案要长得多,但它应该能从我的理解中准确地给出你想要的。

var mapping = {dom: false};
var dom = typeof mapping.allowDom !== "undefined" ? mapping.allowDom : typeof mapping.dom !== "undefined" ? mapping.dom : true;
$('#result').append("" + dom);

更多关于这把小提琴的测试。

http://jsfiddle.net/myra7x2m/

另一种很好的实现形式是通过函数和开关而不使用控制表达式,这使它成为一个更好的if/else块:

dom = (function() {
    switch (false) {
      case mapping.allowDom == null:
        return mapping.allowDom;
      case mapping.dom == null:
        return mapping.dom;
      default:
        return true;
    }
})();

你可以在这里测试

http://jsfiddle.net/w3jtsk5u/

如果你想知道,为什么我比较== null而不是!= null,它仍然有效,是因为我使用了switch(false),所以与之比较的值是false,这否定了表达式。

对于紧凑的朋友,你当然可以写:

dom = (function(){switch(false){
  case mapping.allowDom == null: return mapping.allowDom;
  case mapping.dom == null:      return mapping.dom;
  default:                       return true;
}})();

仍然可读:)

当涉及到布尔值选项时,测试null是最好的方法:

var dom;
if (mapping.allowDom != null) {
  dom = mapping.allowDom;
} else if (mapping.dom != null) {
  dom = mapping.dom;
} else {
  dom = true;
}

我会把上面的内容封装在一个函数或一个Maybe monad中。请注意,这是我使用==!=运算符的唯一用例,任何其他比较总是===!==运算符。因为== null将测试null或undefined。

OR运算符将返回第一个"truthy"值,如果该值被求值为false,则将检查下一个值,直到最后一个值。

因此,只能将false或'falsey'值作为序列中的最后一个默认值。