将零视为真理的模式

我经常做这样的事情:

delay = delay || 24; // default delay of 24 hours 

但我实际上想要允许0和0 || 24 === 24 0 || 24 === 24 ,而不是0

我想知道最好的模式是从命令行接受用户input,还是从任何地方进行input,并且执行相同的逻辑,只将零视为真实。 我认为我发现的最好的模式是做到这一点:

 delay = (delay === 0 ? delay : (delay || 24)); 

首先,它允许像'abc'这样'abc'事情,这是错误的。 但是,如果我提前+它让null滑过,这也是错误的。 其次,非常丑陋,因为它显然是在解决语言缺陷问题,而不是用可用的语言工具做一些优雅的事情。 而不是非常可读。 我正在做的是一个思路,我想在一个实际的代码行(不是技术上的一行,就像这样)。 但是,大部分其他的想法我都得到了:

 delay = typeof delay === 'number' ? delay : 24; // but typeof NaN === 'number', so delay = (!isNaN(delay) && typeof delay === 'number') ? delay : 24; 

请注意,这实际上会用string – 如果我有兴趣接受"" ,那么

 str = typeof str === 'string' ? str : 'default'; 

由于没有NaN洞,这是智能可读的:如果我们有一个string使用,否则使用defaut。

或者这条路线:

 delay = !isNaN(+delay) ? delay : 24; // fails on null delay = !Number.isNaN(+delay) ? delay : 24; // still fails on null // same thing with null check, now way uglier than we started 

所以我仍然喜欢我的哈克三元和布尔逻辑更好。 是的,我正在寻找一个简洁的,单线的解决scheme,因为JS充满了模式,而其他许多语言中聪明的东西在JS中被广泛认可和清晰。 但是,我是新手,并试图学习好的模式,因此,这个问题。

要更加明确的要求:

  • 0需要去0
  • undefined需要去24
  • typeof下的所有实际数字都需要自己typeof ,除了NaN
  • 我强烈地感到null应该去24因为我很less使用的JS代码,对待nullundefined目的。 我觉得最好保持这种方式。
  • 我稍微感觉NaN应该去24因为这更接近|| 模式。 麻烦的事情应该去默认。
  • 'abc'应该到24 – 在我的真实应用程序中,这是用户input,用户不应该错误地input电子邮件。
  • '123abc'理想情况下应该去24 ,转换为Number捕获但parseInt不转换。 我相信电子邮件可以从数字开始,所以这使得这个问题应该被抓住。

下划线或答案是可以接受的,尤其是对那些曾经过我试图“聪明”而不是写2-3线function的人。 这些库的存在恰恰是因为许多简单的2-3行函数在世界各地许多代码库中的许多地方完成同样的事情,而且它们更具可读性,可维护性和可靠性, _.readNumber 。 如果不存在这样的方法,而且我能够提出足够一般的要求,那么我将自己提交一个调查请求,并将其作为对这个问题的回答。 这是我喜欢JS的东西 – 它有一个良好的生态系统,因此很有可能不必编写这些实用程序方法。 由于我特别处理用户input,所以对我来说写一个稍微更专门化的函数并提交给commander.js可能会更好,这是我一直需要的。

假设用户input为一些评论说,然后开始任何可能的string,以便testing它。

 delay = /^(\d+)$/.exec( delay ) ? Number( RegExp.$1 ) : 24; 

注意这也防止负整数,虽然没有作为一个要求给予是荒谬的,因为延误的时间。

没有一个要求提到,所以假设你想要任何数字,否则默认为24,你可以使用这个:

 delay = isFinite(delay) ? delay : 24; 

或者更安全:

 delay = isFinite(parseFloat(delay)) ? delay : 24; 

或者罗伯特柠檬特别的:

 delay = isFinite(parseFloat(delay))|0||24; 

当然, 让别人理解这个语句比句法糖更重要。 你正在编写的代码被人和机器所理解,而不是为了避免工业间谍。

迄今为止最清洁的解决scheme是:

 delay = numberOrDefault(delay, 24); // i = i || 24 doesn't work with i = 0, so this small func takes care of this. function numberOrDefault(input, default) { // a few lines handling your case } 

不要试图滥用语言。 不要试图变聪明 不要试图混淆你的代码。 它不会为你服务,而且会损害你的代码的可维护性和可读性。

function在那里,可以有名字。 他们完全是为了你要找的目的:给一些指令的名字。 使用它们。

怎么样:

 delay = isNaN(parseInt(delay, 10)) ? 24 : delay 

(编辑:我现在在评论中看到了这个build议,那是我在一个控制台上工作的时候发生的,诚实的:D)

如果您绝对要求带有前导数字的string不是有效的,那么您将必须检查它:

 delay = typeof(delay) === "number" && isNaN(parseInt(delay, 10)) ? 24 : delay 

例如,如果我使用你的习惯用语:

 delay = (delay === 0 ? delay : (delay || 24)); 

而“延迟”是“123abc”,你的方法会导致延迟仍然是“123abc”,因为它是一个真值。

Per Shmiddty的评论,如果你不打算做明确的types检查,你需要使用parseInt,以确保你实际上设置delay为整数types; 即使0是真的, delay = delay || 24 如果没有任何types的强制或types检查, delay = delay || 24会将delay设置为string值。 在执行isNaN检查之前强制一个数字可以确保任何不是有效数字的东西(如parseInt所parsing的;具有前导数字的string仍然会isNaN )确保了当您检查isNaN ,结果将意味着“这是一个有效的数字“或”这不是有效的数字“,而不是”这是NaN“或”这是除NaN以外的任何东西“。

如果你正在做types检查,你并不严格需要parseInt,但是我认为从语义angular度来看它仍然是一个好主意,因为它表明你期望并且需要一个整数值。

不要这样做,尽pipe它可以从字面上做你想要的:

 Number.prototype.valueOf=function(){return this||"0";} alert( 0 || 24 )// shows: 24 

我认为这会打破其他脚本,但如果我们可以在JavaScript块级别做这样的事情会很好…