逻辑';和';在javascript中使用对象和值

逻辑';和';在javascript中使用对象和值,javascript,functional-programming,Javascript,Functional Programming,在MichaelFogus的《函数式javascript》一书中,我遇到了一个仍然无法解开的表达式。 以下是函数: function defaults(d){ return function(o, k){ var val = fnull(_.identity, d[k]); return o && val(o[k]); } } 在哪里 function fnull(fun /*, defaults*/){ var defaults = _.rest(


在MichaelFogus的《函数式javascript》一书中,我遇到了一个仍然无法解开的表达式。 以下是函数:

function defaults(d){
  return function(o, k){
    var val = fnull(_.identity, d[k]);
    return o && val(o[k]);
  }
}
在哪里

function fnull(fun /*, defaults*/){
  var defaults = _.rest(arguments);
  return function(/* args */){
    var args = _.map(arguments, function(e, i){
      return existy(e)?e : defaults[i];
    });
    return fun.apply(null, args);
  };
};

function existy(x){return x != null}
(下划线是underline.js库的对象)
以及使用示例:

function doSomething(config){
  var lookup = defaults({critical:108});
  return lookup(config, 'critical');
}

doSomething({critical: 9});
//=> 9
doSomething({});
//=> 108
我在node.js中重新创建了exapmle,它工作得很好,但我想知道为什么逻辑“and”在“default”函数的返回行中

return o && val(o[k]);
这样做有什么意义?我和他一起检查了考试

return val(o[k]);
而且效果也很好。 很难相信这只是一个错误

return o && val(o[k])
意味着如果“o”为真,它将返回“val(o[k])”

给定“expr1&&expr2”:


如果可以将expr1转换为false,则返回expr1;否则,返回expr2。因此,当与布尔值一起使用时,如果两个操作数都为true,&&将返回true;否则,返回false。

逻辑值将确保仅在第一部分为true时才计算第二部分。如果
o
的计算结果不为true,则表达式返回false。否则,它将返回
val(o[k])


这是用来快速检查o是否为false/null/undefined。

这是逻辑表达式中称为short“short circuiting”的智能用法

当逻辑表达式从左到右求值时,将对其进行测试 使用以下规则进行可能的“短路”评估:

false&(任何)
短路评估为false

true | |(任何)
短路评估为true

逻辑规则保证这些评估总是正确的。请注意,上述表达式的
(任意)
部分未进行计算
(表示根本不运行),因此这样做的任何副作用都不会生效这也有好处。

用法:

  • 将易于计算或可能为真/失败的内容放在表达式最左边的位置,以加快表达式的计算速度

  • 例如,
    parOfExpressionLikelyToBeTrue&(表达式的其余部分)
    在大多数情况下甚至不会计算表达式的其他部分。这同样适用于parOfExpressionLikelyToBeTrue | | |(espression的其余部分)

  • 如果计算某些内容非常耗时,则可以使用相同的方法,将其尽可能推回到表达式中的右侧。例如
    (表达式的其余部分)和&ThisCostsALotOfTime
    (表达式的其余部分)| ThisCostsALotOfTime
    。在这里,当表达式的第一部分短路时,您可以在耗时的部分节省时间

  • 短路存在性评估。假设您需要检查对象的属性pr是否为3?你会怎么做<代码>obj.pr==3?是和否。如果财产丢失怎么办?很好,你将得到未定义的,这不是===3。但若物体不在那个里呢。您将尝试读取未定义错误的pr您可以在这里使用短路逻辑,通过防御性并将表达式写成
    (obj | | obj.pr==3)
    ,从中获益。这确保了没有错误,只有正确和错误

  • 短路初始化。假设你想说变量a是b。但是b可能是未定义的。你希望你的变量有一个默认值。您可以编写a=b,然后检查a是否未定义并将其设置为默认值,或者您可以聪明地将其编写为
    a=b|3
    。这样一来,a就是b,或者如果be是未定义的,那么它就是3。Ofc,您可以将此用于后期初始化,也可以使用
    a=a | 3

  • 在尝试运行函数之前,请确保函数的对象存在。与前面提到的属性相同,您可能希望在运行函数之前测试包含函数的对象是否存在。假设对象obj和函数fn是它的属性。您可以像
    obj.fn()
    那样调用该函数。这很好,但如果obj未定义,您将得到一个错误。出于防御性,您可能需要编写:
    obj&&obj.fn()

  • 仅当存在函数时才运行该函数。由于JS中的函数可以传递给其他函数,所以在运行时无法确定它是否存在。出于防御性,您可能希望以(typeof passedFunction==“function”&&passedFunction()的形式运行函数,而只运行passedFunction(),这会产生错误

  • 其他聪明的东西,比如guardian表达式等,它们很复杂,太多了,我记不住所有的东西,为了更好的代码可读性,你应该避免使用它们


“如果可以转换为false,则返回expr1;否则返回expr2。”这意味着什么?如果expr1(您的“o”)可转换为布尔false,则返回false(则不会返回expr2(您的“val(o[k])),否则返回expr2(您的“val(o[k]))所以这只是一个快速检查。谢谢。这是一个以智能方式使用的短路。还有更多类似的防御JS技术。我发布了一个很长的版本,我发现最有用的东西供你在一个地方阅读。它有点长,但如果你投入时间,你的代码我将在速度、稳定性方面受益,或者你可以简单地节省几行代码这是一条聪明的捷径。