web-dev-qa-db-ja.com

真の明示的なチェックは意図的に悪いのですか?

ブール値のtrueを明示的にチェックすることは悪いと考えられていますか?単純なif(success)を実行する方が良いでしょうか?

強く型付けされた言語でのif (someBoolean === true)がどのように恐ろしいコードであるかについてさまざまなジョークを見てきましたが、弱く型付けされた言語でも悪いと考えられますか?

これは、ifステートメントで型強制を行う弱く型付けされた言語に適用されます。

具体的な例は次のとおりです。

var onSuccess = function (JSONfromServer) {
    // explicitly check for the boolean value `true`
    if (JSONfromServer === true) {
         // do some things
    }
}

// pass it to an ajax as a callback
doSomeAjax(onSuccess);

[編集]

この特定のケースでは、success変数はサーバーから返された有効なJSONです。したがって、それは何でもかまいません。ブール値がtrueの場合、成功しました。エラー処理オブジェクトの場合は、処理されます。それが他のものである場合、おそらく静かに処理されます。

問題は、サーバーにtrueをJSONとして返し、アクションが成功した場合を処理するための適切な方法を確認することでした。

JavaScript&AJAXとはいえ、特定のものであることを避けたかったのです。

19
Raynos

私自身、これについて2つの考えがあります。

1つの点では、Javascriptが型強制を処理する方法のため、投稿したコードサンプルは適切です。単純なif (success)は、successtruthyである限り、ifブロックに入ります。空ではない文字列がケースをします。三重等号は、successが確かにブール値trueであることを保証します。これは、短いバージョン(およびおそらく必要なバージョン)で得られるよりも強力な保証です。

しかし、あなたがneed this-つまり、successがブール値、文字列、または整数のどれになるかがわからない場合-それ自体がコードのにおいだと思います。比較の実行方法に関係なく、私は常にブール値になることを避けられない変数と常に比較します。その時点では、同等であるため、どの比較形式を使用するかは問題ではありません。実際、次のような「冗長な」変数も導入します。

var successCount = items.size(); // or some other way to get an integer
var success = successCount > 0;
if (success) {
   ...
}

ええと、ええ。機能的な違いがあるため、比較での===の(明示的な)使用について誰も本当に不満を言うことはないと思います。しかし、同じように、ブールsuccessフラグを明確に使用している場合は、ショートスタイルについて文句を言うべきではないと思います。

(ただし、最初の文に関しては、動的に型付けされた言語でブール値trueを明示的に確認することは、その値が実際に必要なものである場合に悪いことではないと思います。静的型付けがすでに変数をブール値。)

12
Andrzej Doyle

Javascriptでは、ブール値のtrueおよびfalseを超えて、値はtruthyおよびfalsyになる可能性があることを知っておく価値があります。

検討してください:

if (false)     // evaluates to false.
if (0)         // evaluates to false, 0 is falsy.
if ("")        // evaluates to false, empty strings are falsy.
if (null)      // evaluates to false, null values are falsy.
if (undefined) // evaluates to false, undefined values are falsy.
if (NaN)       // evaluates to false, NaN is falsy.

オブジェクトの他のすべての値は真実です。

真と偽の値がロジックのエラーにつながる場合は、===演算子と!==演算子を明示的に使用して、オブジェクトがタイプと値で比較されるようにすることを検討する必要があります。

18
Matthew Abbott

一般に、次のようなブール変数名が必要です。

success, enabled, pass

真の価値を持つ。そう

if(success) //or

if(enabled) //or

if(pass) //or

if(enabled) //or

理解可能かつ論理的に読みやすいです。しかし、次のような変数がある場合:

result, status, port1.bit7

それを書く方が良いです:

if(result == true) //or

if(status == false) //or

if(port1.bit7 == true)

以下の例よりも簡単に理解できるからです。

if(result)
{
  ....
}

可読性は保守性です。

7
LEMUEL ADANE

何がうまくいかないのですか?まさに、何も。最良の場合、関数は何もしません。これは、ランダムな引数をtrueとして受け入れるよりも優れています。

trueをいつも使用する場合は、明示的に確認する必要もあります。

私はPythonで_if foo:_を支持していると確信していますが、ここには大きな違いがあります。それは、結局、ランダムなjQueryプログラマーが長くなり、「ああ!およびnew Boolean() "を使用します。

Seanが_!!_を使用することを提案しているのは、ブール値のみを受け入れたいのか、それとも真実であるのかによって異なります。クリーンなAPIの場合は、ブール値のみを受け入れます。

2
Ivo Wetzel

この会話に追加するために、sessionStorageおよびlocalStorage変数は、今日は文字列としてのみ格納できるため、以下を使用する場合:

sessionStorage.setItem('completed',true);

実際には文字列に変換され、「true」として格納されます。多くの人が、ブール値を使用してifステートメントを使用できるように、この値を操作するメソッドと変換を作成する人を見てきました。

if sessionStorage.getItem('completed') === 'true';

私の意見では十分であり、完全に読みやすく、保守可能です。

1
user3094826

JavaScriptについてはかなり読みましたが、if(success)が悪い習慣だと言う人は見たことがありません。私がやります。 successパラメータは常にブール値になりますか?現時点で、それが別の何かに変わる場合は、関数を編集する必要があります。ただし、if(success)だけを使用する場合は、文字列と空の文字列、1と0のように、他の「真の」値と「偽の」値に対して機能します。

そのパラメーターをブール値に変換したい場合は、ダブルネゲートするだけです:!!success;しかし、それはそのような条件の中で必要ではありません。

1
Andrew Burgess

コードの匂い、言語の匂い、実装の詳細、または慣例の問題ですか?

本当に、それは状況次第です。

すべてのfalse値とすべてのtrue値をバケットに入れると、コードのデザインが悪いか、何らかの理由で本当に問題になるため、違いが重要になるまで、事態が単純化されます。

同じように、Hoareはnull参照を発明したことを謝罪しました。 JavaScriptの設計は、さらに真実な値を追加することで問題を混乱させ、多くは、エラーの追跡を困難にすることを避けるために明示的なチェックを主張するようになっています(Douglas Crockford)。 JavaScriptコミュニティは言語自体を受け入れており、少し行き詰まっています。 Pythonコアチームは、言語設計が物事を混乱させるのではなく、簡略化するように設定されているようであり、コアチームはまだ言語の変更を計画しているため、反対を主張します。小さな反復的な変更慣習であれ、言語設計であれ、時間の経過に伴う大幅な改善の本質です。

どちらも特定の状況に適した戦略です。これが唯一の改善の源であると言っているわけではありませんが、それが現時点での主要な改善の源です。

たとえば、TrueFalseは実際にはPythonではintのサブクラスであり、具体的には0と1です。これにはいくつかの設計上の利点があります。次に、PEP8は、

if a_reference:
    pass

Pythonで実際にNoneを使用する必要があるのは、オプションのパラメーターを指定するときだけです。

def foo(bar=optional): # NOTE I made up this idealistic construct
    """Looks good at the surface"""
    pass

def foo(bar=None):
    """But this is clear to the programmer"""
    pass

JavaScriptは暗黙的にすべての変数をオプションとして持っています:

function foo(x, y, z) {
    // Certainly not clear to the programmer.
}

また、クロックフォード氏は、明確にチェックして言語を明確にすることを提唱しています。

if (foo === undefined) {
    // pass
}

基本的にJavaScriptは、undefinedとして知られるNullリファレンス#2を追加しました。 JavaScript言語がプログラミングコミュニティであまり考慮されていないことも面白いと思います。彼らは、CoffeeScript、GWT、Pyjamasのようなものを使用する複雑さを追加することは、クライアント側の言語を改善するために公正なトレードオフであると考えています。もちろん、追加された複雑さに同意しませんが、JavaScriptを処理する代わりに、少なくとも一時的に利益を得て、手元の仕事をより早く終わらせることができる人がいるのは残念です。

しかし、これは長期的には愚かな決定だと思います。

0
Derek Litz