JavaScript/演算子

演算子(えんざんし、operator)とは、2 + 3の+のように、演算を表す記号のことです。2や3は被演算子(ひえんざんし、operand、オペランド)といいます。JavaScriptには算術演算子以外にもさまざまな演算子があります。変数の代入で使用した=も演算子の一種ですし、コンマ,も演算子の一種です。 演算子はメソッドでは有りません。 演算子はメソッドと異なりオーバーロード出来ません。
加算 (+)、減算 (-)、乗算 (*)、除算 (/) の四則演算をはじめとする基本的な算術演算子が存在します。数値は常に浮動小数点数として扱われます。 BigIntにも演算子を適用できますが、算術演算子の場合両方のオペランドがBigIntである必要があり異なる型が渡されると、暗黙の型変換は行われず TypeErroe となります。 数値の演算で NaN を返すケースは、BigIntではErrorとなります(例えばゼロ除算は数値ではNaNを返しますが、BigInt同士ではRangeErrorがthrowされます)。
加算演算子(かさんえんざんし、addition operator)は+です。
減算演算子(げんざんえんざんし、げんさんえんざんし、subtraction operator)は-です。
乗算演算子(じょうざんえんざんし、じょうさんえんざんし、multiplication operator)は*です。
除算演算子(じょざんえんざんし、じょさんえんざんし、division operator)は/です。
ゼロ除算(ゼロじょざん、ゼロじょさん、division by zero)は例外ではなくInfinity(あるいは-Infinity)を返します。 BigInt 同士のゼロ除算は RangeError となります。
除数・被除数ともゼロの除算はNaNを返します。 BigInt 同士の除数・被除数ともゼロの除算は RangeError となります。
剰余演算子(じょうよえんざんし、REMAINDER operator)は%です。割り算の余りを求めます。
結果は必ず左オペランドの被除数(割られる数)と同じ符号になります。
ゼロ剰余(ゼロじょうよ、REMAINDER by zero)は例外ではなくNaNを返します。 BigInt 同士の剰余は RangeError となります。
a % bはa - b * Math.trunc(a / b)と等価です。 Perl や Ruby のようにa - b * Math.floor(a / b)と等価ではありません。これは IEEE754 の Remainder に定義された挙動で C 言語の libm にある fmod() と同じ動作です。
除数は浮動小数点数でもかまいません(元々 Number は64ビット倍精度浮動小数点数です)。
単項プラス演算子(たんこうプラスえんざんし、unary plus operator)は式を評価し、数値でなかった場合は暗黙な変換に従い数値に変換します。
単項マイナス演算子(たんこうマイナスえんざんし、unary negation operator)は符号を反転させた数(反数)を返します。符号反転演算子(ふごうはんてんえんざんし)、算術否定演算子(さんじゅつひていえんざんし)などという言い方をする人もいます。
a * -1と似ていますが BigInt が渡されても TypeError とはならない点が異なります。
インクリメント演算子(インクリメントえんざんし、increment operator)は変数の値を1増やします。
インクリメント演算子は後置++すると増やす前の値を返し、
++前置すると増やした後の値を返します。
複数のインクリメント演算子を同時に適用することはできません。
x++はx += 1、すなわちx = x + 1と等価です。インクリメント演算子は変数の値を増加させるので、1++のようにリテラル(定数)に対して適用することはできません。
デクリメント演算子(デクリメントえんざんし、decrement operator)は変数の値を1減らします。
デクリメント演算子は後置--すると減らす前の値を返し、
--前置すると減らした後の値を返します。
複数のデクリメント演算子を同時に適用することはできません。
x--はx -= 1、すなわちx = x - 1と等価です。デクリメント演算子は変数の値を減少させるので、1--のようにリテラル(定数)に対して適用することはできません。
冪乗演算子(べきじょうえんざんし)は、第1オペランドを第2オペランドの累乗した結果を返します。Math.pow と同等ですが、オペランドとして BigInt を受け入れることができます。
なお、^はビットごとのXOR演算子です。
ビット演算子(ビットえんざんし、bitwise operator)は、ビット演算の演算子です。ビット演算とは数値を32ビット整数変換し、各ビットに対して行う演算のことです。
a >>> bは捨てられたビットの分だけ左から0を詰めます。 ' >>> は BigInt に適用すると TypeError になります。 ビット演算子は算術演算子よりも優先順位が低いことに注意してください。
+は加算演算子であると同時に、文字列連結演算子(もじれつれんけつえんざんし、string concatenation operator)でもあります。
文字列と数値を連結すると、文字列の方が強いので数値は文字列に変換されます。
これは足し算をしようとして文字列がまじっていると厄介なことになります。
文字列の連結よりも数値の加算を優先させるには、文字列を数値に変換した上で加算しなければなりません。文字列を数値に変換するには、教科書的にはparseInt関数やparseFloat関数、Numberオブジェクトのコンストラクタなどを使いますが、
一般的には単項プラス演算子を使用した方が高速です。
ほかにも1を掛ける (one * 1)、0を引く (one - 0))などの方法があります。 これらの演算子は数値にしか適用できないので、処理系が被演算子を自動的に数値に変換(暗黙的な型変換)するためです。
かつてこの本で、0で符号なし右シフトをする (one >>> 0)あるいは 補数の補数を得る(~~one) を文字列を数値に変換する方法として紹介されていましたが、前者は32ビット符号なし整数に、後者は32ビット符号付き整数への変換となり浮動小数点数を表す文字列に適用すると、、
の様になります。興味深い挙動ですが文字列を数値に変換する方法としては妥当とは言えません。
加算と暗黙の型変換の結果を表にしました。
この表は、二項演算子(+)と様々な値の組み合わせについて見てみました。
if文の条件式などのブーリアンコンテキストでの真理値への変換や、単項+の数値への変換は、また別の規則になります。
代入演算子(だいにゅうえんざんし、assignment operator)は変数に値を代入します。代入した値を返し、結合は右から左です。
複合代入演算子(ふくごうだいにゅうえんざんし、Compound assignment operators)は、x = x OPERATOR yの形式をx OPERATOR= yの形式に短縮表記したものです。代入演算子と同じ優先度を持ち、演算し代入した値を返し、結合は右から左です。OPERATOR=で1つのトークンで、OPERATORと=の間に空白を含めることはできません。 例えば、x *= yはx = x * yと等価です。
分割代入(ぶんかつだいにゅう、Destructuring assignment)は、配列の値やオブジェクトのプロパティを個別の変数に展開することができるJavaScriptの表現方法です。
JavaScriptには、様々な種類の分割代入があります。以下に代表的なものを示します。
このコードは、JavaScriptにおける分割代入の様々な使い方を示しています。
最初の例では、配列の分割代入を使用して、3つの変数 a、b、c にそれぞれ配列 [1, 2, 3] の要素を代入しています。
次に、オブジェクトの分割代入を使用して、オブジェクト person のプロパティ name と age を変数 name と age に代入しています。
その後、別名を指定してオブジェクトの分割代入を行い、変数 firstName と years に person オブジェクトのプロパティ name と age をそれぞれ代入しています。
次に、デフォルト値を指定してオブジェクトの分割代入を行い、空のオブジェクトから name プロパティが Anonymous、age プロパティが 0 のデフォルト値を持つ変数 names と ages を作成しています。
次に、関数の引数としての分割代入を示しています。 foo 関数は、オブジェクト { x, y } を引数として受け取り、そのプロパティを console.log で表示するように定義されています。この関数は、point オブジェクトを引数として呼び出され、その結果、1 2 が表示されます。
最後に、可変長引数を受け取る関数 sum を定義し、 1 と 2 を最初の2つの引数として、残りの引数を可変長引数 rest に代入しています。console.log を使用して、最初の2つの引数の合計値と残りの引数を表示します。sum(1, 2, 3, 4, 5) が呼び出されると、3 と [3, 4, 5] が表示されます。
論理演算子(ろんりえんざんし、logical operator)とは、真偽値を返す論理的な演算子です。短絡評価と副作用に注意してください。
論理積演算子は、両方のオペランドが true であったら true を、それ以外は false を返します。
論理和演算子は、片方または両方のオペランドが true であったら true を、それ以外は false を返します。
否定演算子は、オペランドを論理型に変換した後、true であったら false を、false であったら true を返します。
JavaScriptに排他的論理和演算子は存在しませんが、
と真偽値に変換した後、不一致を評価する式で実現できます。
でも可。
関係演算子(かんけいえんざんし、Relational operator)とは、大小関係あるいは包含関係を比較して真偽値を返す演算子です。
=< や => のようなに = が先にくる関係演算子は存在しないので気をつけてください(特に => はアロー関数の構文で書き方によっては SyntaxError とならず発見困難なバグの原因になります)。大小比較は必ず手前に大なり小なり、後にイコールが来ます。
in 演算子は、プロパティがオブジェクトに含まれると true を返します。for in 文の in とは違います。
instanceof 演算子は、コンストラクタのprototype プロパティがオブジェクトのプロトタイプ・チェーンのどこかに現れるかどうかをテストします。戻り値は、論理値です。
小なり演算子は、左辺が右辺より小さいかどうかをテストします。戻り値は、論理値です。
小なりイコール演算子は、左辺が右辺より小さいあるいは等しいかをテストします。戻り値は、論理値です。
大なり演算子は、左辺が右辺より大きいかどうかをテストします。戻り値は、論理値です。
大なりイコール演算子は、左辺が右辺より大きいあるいは等しいかをテストします。戻り値は、論理値です。
等値演算子(とうかえんざんし、equality operators)とは、比較して真偽値を返す演算子です。
等価演算子は、左辺が右辺と等しいかをテストします。比較は暗黙の型変換の後に行われます。戻り値は、論理値です。
不等価演算子は、左辺が右辺と等しくないかをテストします。比較は暗黙の型変換の後に行われます。戻り値は、論理値です。
同値演算子(厳密一致演算子)は、左辺が右辺と等しいかをテストします。型が異なれば直ちに不一致を返します。戻り値は、論理値です。N
不同値演算子(厳密不一致演算子)は、左辺が右辺と等しくないかをテストします。型が異なれば直ちに不一致を返します。戻り値は、論理値です。
プロパティアクセサ(property accessor)とは、オブジェクトの(メソッドを含む)プロパティにアクセスするための演算子式で、左辺値式です。
ドット記法のプロパティアクセサは、object . propertyの構文で、.を挟んだ二項式です。 ドット記法では、propertyが識別子として有効なときにのみ使え識別子以外を用いると SyntaxError を throw します。
ブラケット記法のプロパティアクセサは、object [ property ]の構文で、[ ]を使った配列アクセス似の記法です。文字列の他、Symbol もキーにできます。
条件が真なら式1を評価しその値を返す、条件が真でなければ式2を評価しその値を返します。
カンマで区切られた式を左から順に評価し、最後の式の値を返す
グループ化演算子は、評価の優先順位を制御します。最上位の優先度を有しますが、短絡評価の影響を受けます。
delete演算子 はオブジェクトからプロパティを取り除きます。
関数名に続く括弧はグループ化演算子ではなく、関数呼び出しです。
new 演算子は、ユーザー定義のオブジェクト型や、コンストラクタ機能を持つ組み込みオブジェクト型のインスタンスを作成します。
式を評価し(結果に関わらず)undefined を返します。
yieldキーワードは、ジェネレータ機能(function*)を一時停止および再開するために使用します。
yield*式は、別のジェネレータやイテレート可能なオブジェクトに処理を委譲します。
typeof演算子(タイプオブえんざんし、typeof operator)はデータ型を返します。
同じ優先順位の演算子(下表参照)が連なった時の評価順序を結合性(けつごうせい、associativity)といいます。
たとえば、a - b - cはa - (b - c)ではなく(a - b) - cと左から右に評価されるため、減算演算子は左結合です。また、a = b = cは(a = b) = cではなくa = (b = c)と評価されるため、代入演算子は右結合です。インクリメント演算子++やデクリメント演算子--は、左辺値式ではないので x++ ++ とすると SyntaxErroor となり結合性は定義されません。
次の式の演算子の結合性を述べ、それに従い括弧を補ってください。