演算子（えんざんし、''operator''）とは、2 + 3の+のように、演算を表す記号のことです。2や3は被演算子（ひえんざんし、''operand''、オペランド）といいます。JavaScriptには算術演算子以外にもさまざまな演算子があります。変数の代入で使用した=も演算子の一種ですし、コンマ,も演算子の一種です。
演算子はメソッドでは有りません。
演算子はメソッドと異なりオーバーロード出来ません。
加算 (+)、減算 (-)、乗算 (*)、除算 (/) の四則演算をはじめとする基本的な算術演算子が存在します。数値は常に浮動小数点数として扱われます。
BigIntにも演算子を適用できますが、算術演算子の場合両方のオペランドがBigIntである必要があり異なる型が渡されると、暗黙の型変換は行われず TypeErroe となります。
数値の演算で NaN を返すケースは、BigIntではErrorとなります（例えばゼロ除算は数値ではNaNを返しますが、BigInt同士ではRangeErrorがthrowされます）。
加算演算子（かさんえんざんし、''addition operator''）は+です[https://tc39.es/ecma262/#sec-addition-operator-plus ECMA-262::13.8.1 The Addition Operator ( + )]。
[https://paiza.io/projects/ySNs2SNCO4Eko8b0HPCE-g 変数twoを1+1で初期化するとtwoの値は2となる]:
const two = 1 + 1;
console.log(two);
実行結果:
2
減算演算子（げんざんえんざんし、げんさんえんざんし、''subtraction operator''）は-です[https://tc39.es/ecma262/#sec-subtraction-operator-minus ECMA-262::13.8.2 The Subtraction Operator ( - )]。
[https://paiza.io/projects/wxzLEVD2-1eOuxIr9L3tXA?language=javascript 変数minus_oneを0-1で初期化するとminus_oneの値は-1となる]:
const minus_one = 0 - 1;
console.log(minus_one);
実行結果:
-1
乗算演算子（じょうざんえんざんし、じょうさんえんざんし、''multiplication operator''）は*です。
const four = 2 * 2; // 変数fourを2×2で初期化するとfourは4となる
console.log(four); // 4
除算演算子（じょざんえんざんし、じょさんえんざんし、''division operator''）は/です。
const one_half = 1 / 2; // 変数one_halfを1÷2で初期化するとone_halfは0.5となる
console.log(one_half); // 0.5
ゼロ除算（ゼロじょざん、ゼロじょさん、''division by zero''）は例外ではなくInfinity（あるいは-Infinity）を返します。
BigInt 同士のゼロ除算は RangeError となります。
console.log( 1 / 0 ); // Infinity
console.log( -2 / 0 ); // -Infinity
console.log( 3 /-0 ); // -Infinity
console.log( -3 /-0 ); // Infinity
console.log( 1n / 0n ); // RangeError: Division by zero
除数・被除数ともゼロの除算はNaNを返します。
BigInt 同士の除数・被除数ともゼロの除算は RangeError となります。
console.log( 0 / 0 ); // NaN
console.log( 0n / 0n ); // RangeError: Division by zero
剰余演算子（じょうよえんざんし、''REMAINDER operator''）は%です。割り算の余りを求めます。
const one = 10 % 3; // 10÷3は3余り1なので変数oneは1となる
console.log(one); // 1
結果は必ず左オペランドの被除数（割られる数）と同じ符号になります。
const minus_one = -10 % 3;
console.log(minus_one); // -1
ゼロ剰余（ゼロじょうよ、''REMAINDER by zero''）は例外ではなくNaNを返します。
BigInt 同士の剰余は RangeError となります。
console.log( 10 % 0 ); // NaN
console.log( 10n % 0n ); // RangeError: Division by zero
''a'' % ''b''は''a'' - ''b'' * Math.trunc(''a'' / ''b'')と等価です。
Perl や Ruby のように''a'' - ''b'' * Math.floor(''a'' / ''b'')と等価ではありません。これは IEEE754 の Remainder に定義された挙動で C 言語の libm にある fmod() と同じ動作です。
const remainder = (a,b) => (a - b * Math.trunc(a/b));
for (let i = -1.2; i <= 1.2; i += 1.2)
  for (let j = -1.3; j <= 1.3; j += 1.3)
    console.log(`${i} % ${j}= ${i%j} (=${remainder(i,j)}), ${i} / ${j} = ${i / j}`);
/*
 -1.2 % -1.3= -1.2 (=-1.2), -1.2 / -1.3 = 0.923076923076923
 -1.2 % 0= NaN (=NaN), -1.2 / 0 = -Infinity
 -1.2 % 1.3= -1.2 (=-1.2), -1.2 / 1.3 = -0.923076923076923
 0 % -1.3= 0 (=0), 0 / -1.3 = 0
 0 % 0= NaN (=NaN), 0 / 0 = NaN
 0 % 1.3= 0 (=0), 0 / 1.3 = 0
 1.2 % -1.3= 1.2 (=1.2), 1.2 / -1.3 = -0.923076923076923
 1.2 % 0= NaN (=NaN), 1.2 / 0 = Infinity
 1.2 % 1.3= 1.2 (=1.2), 1.2 / 1.3 = 0.923076923076923
除数は浮動小数点数でもかまいません（元々 Number は64ビット倍精度浮動小数点数です）。
const theta = Math.PI / 4;
console.log(Math.sin(theta) === Math.sin(theta % (2 * Math.PI))); // true
単項プラス演算子（たんこうプラスえんざんし、''unary plus operator''）は式を評価し、数値でなかった場合は暗黙な変換に従い数値に変換します。
const two = "2";
console.log(+two); // 2
const ary = [undefined, null, false, true, 0, 1, "", "1", [], [2]]
const json = ary.map(x => x === undefined ? "undefined" : JSON.stringify(x))
let s = ""
s += ``
console.log(s)
単項マイナス演算子（たんこうマイナスえんざんし、''unary negation operator''）は符号を反転させた数（反数）を返します。符号反転演算子（ふごうはんてんえんざんし）、算術否定演算子（さんじゅつひていえんざんし）などという言い方をする人もいます。
const one = 1;
console.log(-one); // -1
''a'' * -1と似ていますが BigInt が渡されても TypeError とはならない点が異なります。
インクリメント演算子（インクリメントえんざんし、''increment operator''）は変数の値を1増やします。
let x = 0;
x++;
console.log(x); // 1
インクリメント演算子は後置++すると増やす前の値を返し、
let x = 0;
const y = x++;
console.log(y); // 0
console.log(x); // 1
++前置すると増やした後の値を返します。
let x = 0;
const y = ++x;
console.log(y); // 1
console.log(x); // 1
複数のインクリメント演算子を同時に適用することはできません。
let x = 0;
(x++)++; // SyntaxError: Invalid left-hand side expression in postfix operation
''x''++は''x'' += 1、すなわち''x'' = ''x'' + 1と等価です。インクリメント演算子は変数の値を増加させるので、1++のようにリテラル（定数）に対して適用することはできません。
デクリメント演算子（デクリメントえんざんし、''decrement operator''）は変数の値を1減らします。
let x = 0;
x--;
console.log(x); // -1
デクリメント演算子は後置--すると減らす前の値を返し、
let x = 0;
const y = x--;
console.log(y); // 0
console.log(x); // -1
--前置すると減らした後の値を返します。
let x = 0;
const y = --x;
console.log(y); // -1
console.log(x); // -1
複数のデクリメント演算子を同時に適用することはできません。
let x = 0;
(x--)--; // SyntaxError: Invalid left-hand side expression in postfix operation
''x''--は''x'' -= 1、すなわち''x'' = ''x'' - 1と等価です。デクリメント演算子は変数の値を減少させるので、1--のようにリテラル（定数）に対して適用することはできません。
冪乗演算子（べきじょうえんざんし）は、第1オペランドを第2オペランドの累乗した結果を返します。Math.pow と同等ですが、オペランドとして BigInt を受け入れることができます。
const power = 2 ** 10;
console.log(power); // 1024
なお、^はビットごとのXOR演算子です。
ビット演算子（ビットえんざんし、''bitwise operator''）は、ビット演算の演算子です。ビット演算とは数値を32ビット整数変換し、各ビットに対して行う演算のことです。
''a'' >>> ''b''は捨てられたビットの分だけ左から0を詰めます。
' >>> は BigInt に適用すると TypeError になります。
ビット演算子は算術演算子よりも優先順位が低いことに注意してください。
+は加算演算子であると同時に、文字列連結演算子（もじれつれんけつえんざんし、''string concatenation operator''）でもあります。
const str = "Wiki" + "books";
console.log(str); // "Wikibooks"
文字列と数値を連結すると、文字列の方が強いので数値は文字列に変換されます。
const str = "JavaScript " + 1.5;
console.log(str); // "JavaScript 1.5"
これは足し算をしようとして文字列がまじっていると厄介なことになります。
const one = "1";
const two = one + 1;
console.log(two); // "11" -- console.log()メソッドではわかりにくいですが、2文字の文字列です。
文字列の連結よりも数値の加算を優先させるには、文字列を数値に変換した上で加算しなければなりません。文字列を数値に変換するには、教科書的にはparseInt関数やparseFloat関数、Numberオブジェクトのコンストラクタなどを使いますが、
const one = "1";
const two = parseInt(one) + 1;
console.log(two); // 2
一般的には単項プラス演算子を使用した方が高速です。
const one = "1";
const two = +one + 1;
console.log(two); // 2
ほかにも1を掛ける (one * 1)、0を引く (one - 0))などの方法があります。
これらの演算子は数値にしか適用できないので、処理系が被演算子を自動的に数値に変換（暗黙的な型変換）するためです。
かつてこの本で、0で符号なし右シフトをする (one >>> 0）あるいは 補数の補数を得る(~~one) を文字列を数値に変換する方法として紹介されていましたが、前者は32ビット符号なし整数に、後者は32ビット符号付き整数への変換となり浮動小数点数を表す文字列に適用すると、、
"3.14" >>> 0  === 3
"-3.14" >>> 0 === 4294967293
~~"3.14"  === 3
~~"-3.14" === -3
の様になります。興味深い挙動ですが文字列を数値に変換する方法としては妥当とは言えません。
加算と暗黙の型変換の結果を表にしました。
const ary = [undefined, null, false, true, 0, 1, "", "1", [], [2]]
const json = ary.map(x => x === undefined ? "undefined" : JSON.stringify(x))
let s = ""
s += ``
console.log(s)
この表は、二項演算子(+)と様々な値の組み合わせについて見てみました。
if文の条件式などのブーリアンコンテキストでの真理値への変換や、単項+の数値への変換は、また別の規則になります。
代入演算子（だいにゅうえんざんし、''assignment operator''）は変数に値を代入します。代入した値を返し、結合は右から左です[https://tc39.es/ecma262/#sec-assignment-operators ECMA-262::13.15 Assignment Operators]
。
let x = 0;
console.log(x = 1); // 1
let a, b;
a = b = 0;
複合代入演算子（ふくごうだいにゅうえんざんし、Compound assignment operators）は、x = x OPERATOR yの形式をx OPERATOR= yの形式に短縮表記したものです。代入演算子と同じ優先度を持ち、演算し代入した値を返し、結合は右から左です。OPERATOR＝で１つのトークンで、OPERATORと=の間に空白を含めることはできません。
例えば、x *= yはx = x * yと等価です。
let x = 1;
x += 1;   // x = x + 1
console.log(x); // 2
分割代入（ぶんかつだいにゅう、''Destructuring assignment''）は、配列の値やオブジェクトのプロパティを個別の変数に展開することができるJavaScriptの表現方法です[https://tc39.es/ecma262/#sec-destructuring-assignment ECMA-262::13.15.5 Destructuring Assignment]。
JavaScriptには、様々な種類の分割代入があります。以下に代表的なものを示します。
[https://paiza.io/projects/ijm6a3Z0cMjbRoJGJUUo3w?language=javascript 分割代入の例]:
// 配列の分割代入
const [a, b, c] = [1, 2, 3];
console.log(a); // => 1
console.log(b); // => 2
console.log(c); // => 3
// オブジェクトの分割代入
const person = { name: 'Alice', age: 20 };
const { name, age } = person;
console.log(name); // => 'Alice'
console.log(age); // => 20
// 別名の指定
const { name: firstName, age: years } = person;
console.log(firstName); // => 'Alice'
console.log(years); // => 20
// デフォルト値の指定
const { name: names  = 'Anonymous', age: ages = 0 } = {};
console.log(names); // => 'Anonymous'
console.log(ages); // => 0
// 関数の引数としての分割代入
function foo({ x, y }) {
  console.log(x, y);
}
const point = { x: 1, y: 2 };
foo(point); // => 1 2
// 可変長引数の受け取り
function sum(a, b, ...rest) {
  console.log(a + b);
  console.log(rest);
}
sum(1, 2, 3, 4, 5); 
// => 3
// => [3, 4, 5]
実行結果:
1
2
3
Alice
20
Alice
20
Anonymous
0
1 2
3 
[ 3, 4, 5 ]
このコードは、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''）とは、真偽値を返す論理的な演算子です。短絡評価と副作用に注意してください[https://tc39.es/ecma262/#sec-binary-logical-operators ECMA-262::13.13 Binary Logical Operators]。
論理積演算子は、両方のオペランドが true であったら true を、それ以外は false を返します。
left && right
論理和演算子は、片方または両方のオペランドが true であったら true を、それ以外は false を返します。
left || right
否定演算子は、オペランドを論理型に変換した後、true であったら false を、false であったら true を返します。
! bool
JavaScriptに排他的論理和演算子は存在しませんが、
と真偽値に変換した後、不一致を評価する式で実現できます。
でも可。
関係演算子（かんけいえんざんし、''Relational operator''）とは、大小関係あるいは包含関係を比較して真偽値を返す演算子です[https://tc39.es/ecma262/#sec-relational-operators ECMA-262::13.10 Relational Operators]。
=< や => のようなに = が先にくる関係演算子は存在しないので気をつけてください（特に => はアロー関数の構文で書き方によっては SyntaxError とならず発見困難なバグの原因になります）。大小比較は必ず手前に大なり小なり、後にイコールが来ます。
in 演算子は、プロパティがオブジェクトに含まれると true を返します。for in 文の in とは違います。
prop in obj
instanceof 演算子は、コンストラクタのprototype プロパティがオブジェクトのプロトタイプ・チェーンのどこかに現れるかどうかをテストします。戻り値は、論理値です[https://tc39.es/ecma262/#sec-instanceofoperator ECMA-262::13.10.2 InstanceofOperator ( V, target )]。
obj1 instanceof obj2
小なり演算子は、左辺が右辺より小さいかどうかをテストします。戻り値は、論理値です。
left < right
小なりイコール演算子は、左辺が右辺より小さいあるいは等しいかをテストします。戻り値は、論理値です。
left <= right
大なり演算子は、左辺が右辺より大きいかどうかをテストします。戻り値は、論理値です。
left > right
大なりイコール演算子は、左辺が右辺より大きいあるいは等しいかをテストします。戻り値は、論理値です。
left >= right
等値演算子（とうかえんざんし、''equality operators''）とは、比較して真偽値を返す演算子です[https://tc39.es/ecma262/#sec-equality-operators ECMA-262::13.11 Equality Operators]。
等価演算子は、左辺が右辺と等しいかをテストします。比較は暗黙の型変換の後に行われます。戻り値は、論理値です。
left == right
不等価演算子は、左辺が右辺と等しくないかをテストします。比較は暗黙の型変換の後に行われます。戻り値は、論理値です。
left != right
同値演算子（厳密一致演算子）は、左辺が右辺と等しいかをテストします。型が異なれば直ちに不一致を返します。戻り値は、論理値です。N
left === right
不同値演算子（厳密不一致演算子）は、左辺が右辺と等しくないかをテストします。型が異なれば直ちに不一致を返します。戻り値は、論理値です。
left !== right
{{コラム|0と-0の比較|
0 == -0;  // ES6 では true
0 === -0; // ES6 では true
ES6より前は 0 と -0 は一致しませんでしたが、ES6 以降は  0 と -0 は一致するようになりました。これは厳密一致についても同じです。
プロパティアクセサ（''property accessor''）とは、オブジェクトの（メソッドを含む）プロパティにアクセスするための演算子式で、左辺値式です。
ドット記法のプロパティアクセサは、object . propertyの構文で、.を挟んだ二項式です。
ドット記法では、propertyが識別子として有効なときにのみ使え識別子以外を用いると SyntaxError を throw します。
const object = {};
object.myName = "tom"; // 正常
object.123 = 0; // SyntaxError:
object.my-name = "lisa"; // SyntaxError:
ブラケット記法のプロパティアクセサは、''object'' [ ''property'' ]の構文で、[ ]を使った配列アクセス似の記法です。文字列の他、Symbol もキーにできます。
const object = {};
object["myName"] = "tom"; // 正常
object["123"] = 0; // 正常
object["my-name"] = "lisa"; // 正常
条件が真なら式1を評価しその値を返す、条件が真でなければ式2を評価しその値を返します。
 条件 ? 式1 : 式2 
カンマで区切られた式を左から順に評価し、最後の式の値を返す
 式1, 式2, 式3, 式4, 式5 ...,式n
グループ化演算子は、評価の優先順位を制御します。最上位の優先度を有しますが、短絡評価の影響を受けます[https://tc39.es/ecma262/#sec-grouping-operator ECMA-262::13.2.9 The Grouping Operator]。
 ( 式 )
delete演算子 はオブジェクトからプロパティを取り除きます。
delete プロパティ
関数名に続く括弧はグループ化演算子ではなく、関数呼び出しです。
 関数名 ( 引数列 ) 
new 演算子は、ユーザー定義のオブジェクト型や、コンストラクタ機能を持つ組み込みオブジェクト型のインスタンスを作成します[https://tc39.es/ecma262/#sec-new-operator ECMA-262::13.3.5 The new Operator]。
構文: new コンストラクタ [ ( [ パラメータ列 ] ) ]
[https://paiza.io/projects/dWM8oB-5HTzZe7vbjg29Jw?language=javascript 例]:
/*
 * function 製のコンストラクタに適用した例
 */
const T = function(x = 0) {
    this.x = x;
}
T.prototype.value = function() {
    return this.x;
}
const t = new T(42);
console.log(t.value())
/*
 * class に適用した例
 */
class C {
    constructor(x = 0) {
        this.x = x;
    }
    value() {
        return this.x;
    }
}
const c = new C(13);
console.log(c.value())
実行結果:
42 
13
式を評価し（結果に関わらず）undefined を返します。
 void 式 
yieldキーワードは、ジェネレータ機能（function*）を一時停止および再開するために使用します[https://tc39.es/ecma262/#prod-YieldExpression ECMA-262::YieldExpression]。
 yeild 式 
yield*式は、別のジェネレータやイテレート可能なオブジェクトに処理を委譲します[https://tc39.es/ecma262/#sec-generator-function-definitions-runtime-semantics-evaluation ECMA-262::15.5.5 Runtime Semantics: Evaluation]。
 yeild* 式 
typeof演算子（タイプオブえんざんし、''typeof operator''）はデータ型を返します。
 typeof 式 
typeof 42;              // "number"
typeof "Hello, world!"; // "string"
typeof [1,2,3];         // "object"； Arrayラッパーオブジェクト
typeof new Array();     // "object"； Arrayラッパーオブジェクト
typeof new String("ab");// "object"； Stringラッパーオブジェクト
typeof new RegExp();    // "object"； RegExpラッパーオブジェクト
typeof new Set();       // "object"； Setラッパーオブジェクト
typeof new WeakSet();   // "object"； WeakSetラッパーオブジェクト
typeof new Map();       // "object"； Mapラッパーオブジェクト
typeof new WeakMap();   // "object"； WeakMapラッパーオブジェクト
typeof function(){};    // "function"
typeof true;            // "boolean"
typeof void 0;          // "undefined"
typeof null;            // "object"; ラッパーではなく互換性のための仕様
typeof 123n;            // "bigint"
typeof Symbol();        // "symbol"
typeof {};              // "object"
同じ優先順位の演算子（下表参照）が連なった時の評価順序を結合性（けつごうせい、associativity）といいます。
左結合（ひだりけつごう、left-associative）
右結合（みぎけつごう、right-associative）
たとえば、a - b - cはa - (b - c)ではなく(a - b) - cと左から右に評価されるため、減算演算子は左結合です。また、a = b = cは(a = b) = cではなくa = (b = c)と評価されるため、代入演算子は右結合です。インクリメント演算子++やデクリメント演算子--は、左辺値式ではないので x++ ++ とすると SyntaxErroor となり結合性は定義されません。
次の式の演算子の結合性を述べ、それに従い括弧を補ってください。
右結合：typeof ( typeof object )と解釈されます。
左結合：p == q == rは( p == q ) == rと解釈されます。
右結合：a > 0 ? 1 : ( a < 0 ? -1 : 0 )と解釈される条件演算子は短絡評価されるので、条件式が真であった場合には第三項は評価されないです。。
左結合：( a, b ), cと解釈されます（式の値は、c となります）。