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

时间:2017-12-13 09:06:44

标签: javascript functional-programming


在书中的功能性javascript'迈克尔·福格斯(Michael Fogus),我面对一种我仍然无法动摇的表情。 这是功能:

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}

(下划线是Underscore.js库的对象)
以及使用的例子:

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

doSomething({critical: 9});
//=> 9
doSomething({});
//=> 108

我在node.js中重新创建了exapmle并且工作正常,但我想知道为什么逻辑'和'在'默认'的返回行中功能

return o && val(o[k]);

这样做有什么意义?我用

检查了这个问题
return val(o[k]);

它也运作良好。 很难相信这只是一个错误...

3 个答案:

答案 0 :(得分:1)

逻辑并且将确保仅在第一部分为真时评估第二部分。如果o未计算为true,则表达式返回false。否则,它返回val(o[k])

这用作快速检查以查看o是否为false / null / undefined。

答案 1 :(得分:0)

return o && val(o[k])

表示如果“o”为TRUE,则返回“val(o [k])”

给出“expr1&& expr2”:

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

答案 2 :(得分:0)

这是对短线"短路"的巧妙使用。在逻辑表达式中。

  

当逻辑表达式从左到右进行评估时,它们会被测试   可能的"短路"评估使用以下规则:

     

false && (anything)短路评估为假。

     

true ||(anything)短路评估为真。

逻辑规则保证这些评估始终是正确的。请注意,以上表达式的(anything)部分未被评估(意味着根本没有运行),因此这样做的任何副作用都不会生效。 它也有好处。

用法:

  • 通过在表达式的最左侧位置放置易于计算或可能为真/失败的内容,使表达式评估更快。

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

  • 如果计算某些东西非常耗时,可以使用相同的方法,在表达式中将其推回到右侧。例如(rest of the expression) && ThisCostsALotOfTime(rest of the expression) || ThisCostsALotOfTime。当表达式的第一部分短路时,您可以节省耗时部分的时间。

  • 短路存在评估。让我们说你需要检查你的对象的属性是否是3?你会怎么做? obj.pr === 3?是的,不是。如果财产遗失怎么办?很好,你会得到未定义的,但不是=== 3.但如果对象不在那里会怎么样。您将尝试读取未定义错误的pr。 你可以在这里使用短路逻辑,通过防御来获益,并将表达式写成(obj || obj.pr === 3)。这确保没有错误,只有真和假。

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

  • 在尝试运行函数之前确保函数对象存在。与之前提到的属性相同,如果在运行函数之前存在包含该函数的对象,则可能需要测试。让我们说你有对象obj和函数fn作为它的属性。您可以将此功能称为obj.fn()。没问题,但如果obj未定义,你将收到错误。保守你可能想写:obj && obj.fn()

  • 仅在有功能时才运行该功能。因为JS中的函数可以传递给其他函数,所以在运行时它无法确定。作为防御者,你可能想要运行你的函数(typeof passedFunction ===" function"&& passedFunction()而不是passFunction(),这会产生错误。

  • 其他智能的东西,比如监护人的表达等,这些都是复杂的,太多了,我不记得所有这些,你应该避免使用它们以获得更好的代码可读性。