在书中的功能性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]);
它也运作良好。 很难相信这只是一个错误...
答案 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(),这会产生错误。
其他智能的东西,比如监护人的表达等,这些都是复杂的,太多了,我不记得所有这些,你应该避免使用它们以获得更好的代码可读性。