Javascript 将零视为真实的模式

Javascript 将零视为真实的模式,javascript,node.js,Javascript,Node.js,我经常做这样的事情: delay = delay || 24; // default delay of 24 hours 但是我实际上想允许0,并且0 | 24==24,而不是0 我想知道最好的模式是从命令行获取用户输入,或者从任何地方获取输入,并执行相同的逻辑,只将零视为真实。我认为我找到的最佳模式就是这样做: delay = (delay === 0 ? delay : (delay || 24)); 首先,它允许像'abc'这样的事情,这是非常错误的。但是如果我在早期的+中加入一个,它

我经常做这样的事情:

delay = delay || 24; // default delay of 24 hours
但是我实际上想允许0,并且
0 | 24==24
,而不是
0

我想知道最好的模式是从命令行获取用户输入,或者从任何地方获取输入,并执行相同的逻辑,只将零视为真实。我认为我找到的最佳模式就是这样做:

delay = (delay === 0 ? delay : (delay || 24));
首先,它允许像
'abc'
这样的事情,这是非常错误的。但是如果我在早期的
+
中加入一个,它会让
null
通过,这也是错误的。其次,非常难看,因为它显然是在解决语言缺陷,而不是利用可用的语言工具做一些优雅的事情。而且可读性不强。我所做的只是一个思路,我希望用一行实际的代码(而不是像这样一行技术性的代码)来完成。但我的大多数其他想法变得更加丑陋:

delay = typeof delay === 'number' ? delay : 24; // but typeof NaN === 'number', so
delay = (!isNaN(delay) && typeof delay === 'number') ? delay : 24;
请注意,这实际上适用于字符串-如果我对接受
”感兴趣,那么

str = typeof str === 'string' ? str : 'default';
因为没有
NaN
洞,这是智能可读的:如果我们有一个字符串,就使用它,否则就使用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
所以我还是更喜欢我的三元逻辑和布尔逻辑。是的,我正在寻找一个精简的、一行的解决方案,因为JS中充斥着模式,而在许多其他语言中最聪明的东西在JS中是公认的、可读的和清晰的。但我是个新手,正在努力学习好的模式,因此,我提出了这个问题

更明确的要求是:

  • 0
    需要转到
    0
  • 未定义
    需要转到
    24
  • typeof
    下的所有实际数字都需要转到它们自己,除了
    NaN
  • 我强烈觉得
    null
    应该转到
    24
    ,因为我很少使用JS代码来故意区别对待
    null
    未定义的
    。我觉得这样比较好
  • 我稍微觉得
    NaN
    应该转到
    24
    ,因为这更符合
    |
    模式。虚假的东西应该违约
  • 'abc'
    应该转到24-在我的实际应用程序中,这是用户输入,用户不应该错误地键入,比如电子邮件
  • '123abc'
    理想情况下应该转到
    24
    ,该转换到
    Number
    会捕获,但
    parseInt
    不会捕获。我相信电子邮件可以从数字开始,所以这让我明白了这是一件应该被抓住的事情
下划线或lodash答案是可以接受的,特别是对于那些教导我尝试“聪明”而不是编写2-3行函数的人。这些库的存在正是因为在世界各地的许多代码库中,有许多简单的2-3行函数在许多地方完成相同的任务,而将这些库隔离为类似于
\uuu.readNumber
的对象则更具可读性、可维护性和健壮性。如果没有这样的方法存在,并且我能够提出足够的一般要求,我将自己提交一份民意测验请求,并将其作为这个问题的答案发布。这是我喜欢JS的地方——它有一个很好的生态系统,不必编写这些实用方法。因为我特别处理用户输入,所以我最好编写一个更专业的函数并提交给commander.js,这正是我一直需要的地方。

怎么样:

delay = isNaN(parseInt(delay, 10)) ? 24 : delay
(编辑:我现在在评论中看到了这个建议。这发生在我在控制台中解决这个问题时,老实说。:D)

如果您绝对要求带前导数字的字符串无效,则必须进行打字检查:

delay = typeof(delay) === "number" && isNaN(parseInt(delay, 10)) ? 24 : delay
例如,如果我使用你的成语:

delay = (delay === 0 ? delay : (delay || 24));
“延迟”是“123abc”,您的方法将导致延迟仍然是“123abc”,因为它是真实的值

根据Shmidty的评论,如果不进行显式类型检查,则需要使用parseInt来确保实际将
delay
设置为整数类型;即使0是真的,如果在没有任何强制或类型检查的情况下传递了一个字符串值,那么执行
delay=delay | | 24
也会将
delay
设置为字符串值。在执行isNaN检查之前强制输入一个数字可以确保任何无效的数字(如parseInt所分析的;带前导数字的字符串仍然会忽略)可以确保当您检查isNaN时,结果将表示“这是一个有效的数字”或“这不是一个有效的数字”,而不是“这是NaN”或“这是一个无效的数字”“这是除了楠以外的任何东西”


如果你在做类型检查,你不需要严格地使用parseInt,但我认为从语义的角度来看,这仍然是一个好主意,因为它表明你期望并且需要一个整数作为该值。

没有任何地方提到要求
int
,所以假设你想要任何数字,否则默认为24,你可以使用以下命令:

delay = isFinite(delay) ? delay : 24;
或者更安全:

delay = isFinite(parseFloat(delay)) ? delay : 24;
或者罗伯特·莱蒙特辑:

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

当然,让其他人一目了然地理解语句比语法糖分更重要。你编写的代码是为了让人和机器理解,而不是为了避开工业间谍。

假设用户输入的内容如某些评论所说,那么它会以任何可能的字符串开头,因此不妨对其进行测试

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

注意,这也可以防止负整数,虽然不作为要求给出,但作为时间延迟是毫无意义的。

到目前为止,最干净的解决方案是:

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
}
不要试图滥用语言。不要试图变得聪明。不要试图混淆你的代码。它只会服务于你的自我,并且会损害代码的可维护性和可读性

函数在那里,可以有名称。它们完全是为了您想要的目的而做的:为一些指令串命名。使用它们。

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