なぜ論理演算子(||、&&など)の複合代入演算子がないのですか?


20

ECMA-262、パート11.13によると、複合割り当て演算子の完全なリストは次のとおりです*= /= %= += -= <<= >>= >>>= &= ^= |=

パート11.11によると、var c = a || b置くaに値をc場合はToBoolean(a)trueで、入れますbに値をcそれ以外の場合は。そのため、論理ORは合体演算子としてよく使用されます。たとえば、

function (options) {
    options = options || {};
}

多くの場合、上記のように、合体を使用して変数のデフォルト値を指定しますa = a || b

複合代入演算子||=は非常に便利で、上記のコードを短く簡潔に書くことができますa ||= b。ただし、そこにはありません(ただし*=+=および他の複合代入演算子はあります)。

問題は、なぜですか?


2
私は%=演算子さえ存在していると信じられないほど困惑しています。誰がそれが必要だと決めたのですか?これらの演算子の一部は、不適切な言語設計の決定のようです。
ジョナサンリッチ

2
@JonathanRich:なぜ%=がないのですか?これらの割り当て演算子のいずれかを使用する場合、遅かれ早かれ、開発者(penarturなど)は、演算子が他の演算子よりも「同等」である理由を不思議に思うでしょう。
ケビンクライン

4
@JonathanRich Cryptoは、モジュラスを大幅に使用します。Furthemore、算術代入演算子への演算の残りの部分で希望の直交性は、(1つの想定している場合があり+=*=-=/=、なぜでしょう%=仕事?)。

4
@JonathanRich:何かが円形で、それを正規化したい場合、angle %= 360またはvertexIndex %= numberOfVertices(閉じたポリゴンの頂点リストの場合)演算子は便利です。
セバスチャンネグラスズ

1
2007年(誰かと主張している)のブレンダンアイヒは、それ||=を宣言し、&&=近日中に発表することに注意してください。 2つの便利な機能ですが、&opの代入操作形式をそのままにする理由はありません。」
Phrogz 14年

回答:


12

考えられる理由の1つは、論理演算子&&||「短絡」動作があることです。およびの右側のオペランドは&&||必要でない限り評価されません。おそらくこの理由のために、言語設計者は式のような意味がa ||= f()明白ではないと判断し、そのような演算子は除外したほうがよいと判断しました。


2
はい。たとえば、多くの人々はそれa ||= bをとして解釈すべきであると信じていますa = a || bが、実際にはそうすることができますa || a = bRubyのように)。セッターに副作用がある場合、それらは異なる場合があります。どちらかを選択することは、もう一方のキャンプのユーザーにとって悪いことです。個人的にはこのa || a = b方法(Rubyの方法)が好きですが、誰もがそれで満足しているかどうかはわかりません。
フランクリンゆう

8

「この言語機能が実装されなかった理由」に関するすべての質問に対する一般的な答えは、言語を設計したチームが、利益がコストを上回らないと判断したことです。

コストにはさまざまな形があります。言語機能を実装するには時間と労力がかかりますが、複雑さの本質的なコストもあります。機能は、潜在的な利点に比例して、言語をより複雑または曖昧にしますか?

仮想||=演算子は、他の複合代入演算子とは根本的に異なることを行います。他の演算子は純粋に数学的な性質を持っていますが、これは異なります(説明したコンテキストで)ある値を別の値置き換えます。

この曖昧さ(演算子はコンテキストに応じて2つの異なる機能を実行します)を考えると、言語に含まれていない理由を見るのは難しくありません。あなたはその変化を述べていますが

function (options) {
    options = options || {};
}

function (options) {
    options ||= {};
}

nullの合体を実行することは価値のある機能ですが、その利点は私にはあまり明確ではありません。値の置換が発生する場合、等号の右側に両方の値があり、そのような置換が発生する可能性があることを視覚的に示すことが論理的(かつ明確)に思えます。

C#は異なるパスを取り、null合体に特定の演算子を使用します。


1
コードを読むとき、最初の例はより自然に読みます-「オプションはオプションに等しいか、何もありません」-2番目と比較して-「オプションに等しい、または何もありません」。私はこれがちょうど含まれていないもう一つの理由である「または等しい」演算子を考える
アンディ・ハント

あなたの答えに優れたオープニング。そして、あなたの答えの始まりは、タグのウィキ内に属していると思います。

3
@AndyBursh同じロジックを任意の複合代入演算子に適用できます。「XがXに2倍」は、「Xが2に等しい」に比べて自然に読み取ります。
ペナルトゥール

2
入力にfoo = foo || barfoo2回入力する必要があることに注意してください。これは面倒であり、タイプミスをリファクタリングする傾向があります。
Phrogz 14年

1
「数学」の意味を誤解していると思いますが、おそらくブール代数を聞いたことがあるでしょう。||=nullの合体演算子として使用するために非ブール型を強制することは直感的ではなく、実際にはコード形式では鈍感に見えることに同意します。有用になるのは、ブール演算を行おうとしているときです。function fulfill(inValue) { if(resolved || rejected) return false; /* Do stuff here */ return true; } resolved ||= fulfill(value)
ジョスフェリー14

3

あなたは正しい、それ||=は便利な構造です。Perlに存在します。

実際、Perlはこれらすべてを利用可能にします。

**=    +=    *=    &=    <<=    &&=   -=    /=    
|=     >>=   ||=   .=    %=     ^=    //=   x=

これらのいくつかは素晴らしい(.=文字列の最後に何かを追加する)、そうでない(&&=???それと変数の両方が真である場合、変数は右側に設定されると思います。しかし、なぜあなたはこれをするでしょうか? ?)

言語に含まれるものは、実際にはその設計哲学の特徴です。


3
stackoverflow.com/questions/12589467/...何のため&&=の手段/ありません。
マット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.