5

私はよく次のようなことをします。

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

0 || 24 === 24しかし、実際には の代わりに0 と を許可したいのです0

コマンドラインからユーザー入力を取得する、またはどこからでも入力を取得し、同じロジックを実行して、ゼロのみを真実として扱うのが最善のパターンであると考えています。私が見つけた最良のパターンは、まさにそれを行うことだと思います:

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

まず、 のようなことを許可しますが'abc'、これは本当に間違っています。しかし、私が早く入れると、それはすり抜けてしまいます。これも間違っています+. null第二に、非常に醜いです。なぜなら、利用可能な言語ツールでエレガントなことをするのではなく、言語の欠陥を明らかに回避しているためです。そしてひどく読めません。私は1行の思考で何かをしていて、実際の1行のコードでそれをやりたいと思っています(このような技術的な1行ではありません)。しかし、私が持っていた他のほとんどのアイデアはさらに醜くなります。

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、これはインテリジェントに読み取り可能であるため、文字列がある場合はそれを使用し、そうでない場合はデフォルトを使用します。

またはこのルート:

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

だから私はまだハッキーな三項論理とブール論理の方が好きです。はい、私は要約された 1 行のソリューションを探しています。なぜなら、JS にはパターンがたくさんあり、他の多くの言語で優れていることは、JS でよく認識され、読みやすく、明確であるためです。しかし、私は初心者で、良いパターンを学ぼうとしているので、この質問です.

要件をより明確にするには:

  • 0に行く必要があります0
  • undefinedに行く必要があります24
  • typeofを除いて、下のすべての実際の数値は自分自身に移動する必要がありNaNます。
  • と を意図的に異なる方法で処理する JS コードを使用することはほとんどないため、にnull行く必要があると強く感じています。このままの方がいいような気がします。24nullundefined
  • これはパターンにより厳​​密に従うため、NaN行くべきだと少し感じます。偽物はデフォルトにすべきです。24||
  • 'abc'24 に移動する必要があります - 私の実際のアプリケーションでは、これはユーザー入力であり、ユーザーは間違って入力してはいけません。たとえば、電子メールです。
  • '123abc'24の変換はキャッチしますが、NumberキャッチparseIntしません。メールは数字で始めることができると私は信じているので、これはこれがキャッチされるべきものであることを強調しています.

アンダースコアまたはロダッシュの回答は 、特に、2 ~ 3 行の関数を記述する代わりに「賢く」なろうと私に教えてくれた人には受け入れられます。これらのライブラリが存在するのは、世界中の多くのコード ベースの多くの場所で同じことを実行する単純な 2 ~ 3 行の関数が多数存在するためです。たとえば、_.readNumber. そのような方法が存在せず、一般的な十分な要件を思いつくことができる場合は、自分で投票リクエストを送信し、この質問への回答として投稿します. これは私が JS で気に入っていることですこれらのユーティリティ メソッドを作成する必要があります。私は特にユーザー入力を扱っているので、もう少し特殊な関数を作成して commander.js に送信する方が良いかもしれません。

4

5 に答える 5

4

要件はどこにも記載されていないため、任意のint数が必要であると仮定すると、それ以外の場合はデフォルトで 24 に設定され、これを使用できます。

delay = isFinite(delay) ? delay : 24;

またはより安全:

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

またはロバートレモンスペシャル:

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

もちろん、他の人に一目でステートメントを理解してもらうことは、構文糖衣よりも重要です。産業スパイを防ぐためではなく、人間と機械が理解できるようにコードを書いています。

于 2013-07-02T19:34:12.487 に答える
4

はるかにクリーンなソリューション:

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
}

言語を乱用しようとしないでください。賢くなろうとしないでください。コードを難読化しようとしないでください。それはあなたのエゴ以外には役に立たず、コードの保守性と可読性を損なうことになります。

関数があり、名前を持つことができます。それらはまさにあなたが探している目的のために行われています: いくつかの命令に名前を付けます. それらを使用します。

于 2013-07-02T19:48:02.870 に答える
0

How about:

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

(Edit: I now see this suggestion in the comments. That happened while I was working this out in a console, honest. :D)

If you absolutely require that strings with leading numbers not be valid, you're going to have to typecheck it:

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

For example, if I use your idiom:

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

And "delay" is `"123abc", your method will result in delay still being "123abc", since it is a truthy value.

Per Shmiddty's comment, if you aren't going to do the explicit type check, you need to use parseInt to ensure that you're actually setting delay to an integer type; even if 0 were truthy, doing delay = delay || 24 would set delay to a string value if one were passed without any kind of coercion or type check. Coercing to a number before doing the isNaN check ensures that anything that isn't a valid number (as parsed by parseInt; strings with leading numbers will still slip by) ensures that when you check isNaN, the result will mean "this is a valid number" or "this is not a valid number", rather than "this is NaN" or "this is anything except NaN".

If you're doing the type check, you don't strictly need the parseInt, but I'd argue that it's still a good idea from a semantics perspective, since it indicates that you expect and require an integer for that value.

于 2013-07-02T19:25:28.240 に答える