関数を使用したJavaScriptの三項演算子の例


91

私はjQuery 1.7.1を使用しています

JavaScriptの三項演算子を使用して、単純なif / elseステートメントを置き換えようとしています。私はいくつかの場所で成功しています。確かにうまくいかないと思ったとき、他の作業に成功したときは驚きましたが、とにかく試しました。

元のステートメントは次のとおりです。

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    if (IsChecked == true){
        removeItem($this);
    } else {
        addItem($this);
    }
}

三項演算子を使用した同じ関数を次に示します。

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    (IsChecked == true) ? removeItem($this) : addItem($this);
}

使用していた例はすべて、次のように変数を設定するだけだったので驚きました。

x = (1 < 2) ? true : false;

私の質問は、これが「通常の」使用であるかどうかであり、ほとんどのバージョンのJavaScriptで機能しますか?どこで失敗しますか?他にそれほど明白でない使用法はありますか?

更新-「現実世界」のアドバイスをありがとう!!!

私はこれを私の関数として使用しています:

function updateItem() {
    $this = $(this);
    $this.hasClass("IsChecked") ? removeItem($this) : addItem($this);
}

それは正常であり、問​​題なく動作します。一般的に、三項演算子を使用すると読みやすさが難しくなりますが、あなたの場合は問題なく見えます。
Selvakumar Arumugam 2012

1
うーん....どちらも同じ引数を受け入れるため、これを行うこともできます(IsChecked ? removeItem : addItem)($this)。ただし、質問に答えるには、はい、これは正常であり、必要な状況で保守性や可読性を損なうことがなければ、3項演算子の使用に問題はありません。jsfiddle.net/vsB3f
ケビンB

if($this.hasClass("IsChecked")) removeItem($this); else addItem($this)適切な方法です。三項演算子は、このようなケースではなくfoo(isChecked ? 'bar' : meow());、(then / elseブロックで何をしても「戻り値」を気にする場合など)
ThiefMaster

1
あなたの例では、これを支持して最初の行をスキップしてください: $(this).hasClass("IsChecked") ? removeItem($this) : addItem($this); コードをそのまま1行で理解できるので、私の経験則に適合します(以下の投稿を参照)。私のために働く。
Surreal Dreams

回答:


189

えっと、あなたの質問には三元構文のかなりエキサイティングな使い方がいくつかあります。私は最後のものが一番好きです...

x = (1 < 2) ? true : false;

ここでの三項の使用はまったく必要ありません-あなたは単に書くことができます

x = (1 < 2);

同様に、3項ステートメントの条件要素は常にブール値として評価されるため、次のように表現できます。

(IsChecked == true) ? removeItem($this) : addItem($this);

単に:

(IsChecked) ? removeItem($this) : addItem($this);

実際、IsChecked一時的なものも削除します。

($this.hasClass("IsChecked")) ? removeItem($this) : addItem($this);

これが許容できる構文であるかどうかについては、確かです!これは、読みやすさに影響を与えずに、4行のコードを1行に減らす優れた方法です。私があなたに与える唯一の助言は、同じ行に複数の三項ステートメントをネストすることを避けることです(それは狂気です!)


あなたは、クラス名にアッパーケースを使用しないようにしたい場合があります(にisCheckedになってきては、チェックされている)stackoverflow.com/questions/1547986/...
エイドリアンはして

JSは、ファーストクラスの機能を持っています($this.hasClass("isChecked") ? removeItem : addItem)($this)
ClojureMostly

22

3値スタイルは、一般的にスペースを節約するために使用されます。意味的には、それらは同じです。読みやすさを犠牲にしたくないので、完全なif / then / else構文を使用することを好みます。

ほとんどすべての場合、完全なif / then / else形式が使用されます。各ブランチでより大きなコードブロックに入る場合、マルチブランチのif / elseツリーがある場合、または長い文字列に複数のelse / ifがある場合は特に人気があります。

三項演算子は、単純な条件に基づいて変数に値を割り当てる場合や、非常に短い結果で複数の決定を行う場合によく使用されます。あなたが引用する例は、式が余分なロジックなしで2つの値の1つに評価されるため、実際には意味がありません。

良い考え:

this > that ? alert(this) : alert(that);  //nice and short, little loss of meaning

if(expression)  //longer blocks but organized and can be grasped by humans
{
    //35 lines of code here
}
else if (something_else)
{
    //40 more lines here
}
else if (another_one)  /etc, etc
{
    ...

あまり良くない:

this > that ? testFucntion() ? thirdFunction() ? imlost() : whathappuh() : lostinsyntax() : thisisprobablybrokennow() ? //I'm lost in my own (awful) example by now.
//Not complete... or for average humans to read.

if(this != that)  //Ternary would be done by now
{
    x = this;
}
else
}
    x = this + 2;
}

本当に基本的な経験則では-あなたは同様またはより良い1行に全体を理解することができますか?TernaryはOKです。それ以外の場合は展開します。


7

あなたが投稿した例について特にトリッキーなことは何もありません。

三項演算子では、最初の引数(条件付き)が評価され、結果がのtrue場合は2番目の引数が評価されて返され、そうでない場合は3番目の引数が評価されて返されます。これらの引数はそれぞれ、関数呼び出しを含む任意の有効なコードブロックにすることができます。

次のように考えてください。

var x = (1 < 2) ? true : false;

次のように書くこともできます:

var x = (1 < 2) ? getTrueValue() : getFalseValue();

これは完全に有効であり、それらの関数は、値を返すことに関連するかどうかに関係なく、任意のコードを含むことができます。さらに、関数の結果を何かに割り当てる必要がないのと同様に、3項演算の結果を何かに割り当てる必要はありません。

(1 < 2) ? getTrueValue() : getFalseValue();

これらを任意の関数に置き換えるだけで、例のようなものが残ります。

(1 < 2) ? removeItem($this) : addItem($this);

次のように書くことができるので、最後の例では実際には3項はまったく必要ありません。

x = (1 < 2);  // x will be set to "true"

6

三項演算子をネストする場合は、次のようなことをしたいと思います。

   var audience = (countrycode == 'eu') ? 'audienceEU' :
                  (countrycode == 'jp') ? 'audienceJP' :
                  (countrycode == 'cn') ? 'audienceCN' :
                  'audienceUS';

書き込み/読み取りの方が次の場合よりもはるかに効率的です。

var audience = 'audienceUS';
if countrycode == 'eu' {
   audience = 'audienceEU';
} else if countrycode == 'jp' {
   audience = 'audienceJP';
} else if countrycode == 'cn' {
   audience = 'audienceCN';
}

すべての優れたプログラミングと同様に、プロジェクトの完了後に空白を使用すると、コードを読む必要がある人にとってすべてが便利になります。


6
ネストされた3項が読みやすく、デバッグしやすいという上記のコメントに強く同意しません。個人的には、ネストされたelse / ifブロックがルックアップテーブルまたはスイッチステートメントで置き換えられることを望みます
JonnyReeves 2013

@JonnyReevesが同意-通常、ネストされた3進構文は、さまざまな条件(たとえば、数値のモジュロ)をチェックするときに最適に使用されます
AlexFoxGill

6

私からも何かを追加したいと思います。

三項演算子で関数を呼び出す他の可能な構文は次のとおりです。

(condition ? fn1 : fn2)();

同じパラメーターのリストを両方の関数に渡す必要がある場合に便利です。そのため、それらを1回だけ記述する必要があります。

(condition ? fn1 : fn2)(arg1, arg2, arg3, arg4, arg5);

メンバー関数名でも三項演算子を使用できます。これは、個人的にスペースを節約するために非常に気に入っています。

$('.some-element')[showThisElement ? 'addClass' : 'removeClass']('visible');

または

$('.some-element')[(showThisElement ? 'add' : 'remove') + 'Class']('visible');

もう一つの例:

var addToEnd = true; //or false
var list = [1,2,3,4];
list[addToEnd ? 'push' : 'unshift'](5);

2

質問への回答はすでにわかっています。

ただし、ここで1点追加します。これは、真または偽の場合だけではありません。下記参照:

var val="Do";

Var c= (val == "Do" || val == "Done")
          ? 7
          : 0

ここで、valがDoまたはDoneの場合、cは7になり、それ以外の場合は0になります。この場合、cは7になります。

これは実際には、このオペレーターの別の視点です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.