加算 (+)

加算 (+) 演算子は、数値オペランドの合計または文字列の連結を生成します。

試してみましょう

構文

js
x + y

解説

演算子 + は数値の加算と文字列の連結という 2 つの異なる操作のためにオーバーロードされています。評価するとき、まず両方のオペランドをプリミティブに変換します。その後、 2 つのオペランドの型がテストされます。

  • 一方が文字列の場合、もう一方のオペランドも文字列に変換され、連結されます。
  • もし両方が長整数であれば、長整数同士の加算が行われます。一方が長整数で、もう一方が長整数でない場合、TypeError 例外が発生します。
  • そうでない場合は、両辺が数値へ変換され、数値同士の加算が行われます。

文字列の連結はテンプレートリテラルString.prototype.concat() と等価だと思われがちですが、そうではありません。加算は valueOf() を優先的に呼び出して、式をプリミティブに変換します。一方、テンプレートリテラルと concat()toString()を優先的に呼び出し、式を文字列に変換します。式が @@toPrimitive メソッドを持っている場合、文字列連結は "default" をヒントとしてそれを呼び出しますが、テンプレートリテラルは "string" を使用します。これは、文字列表現とプリミティブ表現が異なるオブジェクト、例えば、 Temporal のように valueOf() メソッドが例外を発生するようなオブジェクトにとって重要です。

js
const t = Temporal.Now.instant();
"" + t; // TypeError が発生
`${t}`; // '2022-07-31T04:48:56.113918308Z'
"".concat(t); // '2022-07-31T04:48:56.113918308Z'

"" + x を使用して文字列に変換を行わないことをお勧めします。

数値の加算

js
// 数値 + 数値 -> 加算
1 + 2; // 3

// 論理値 + 数値 -> 加算
true + 1; // 2

// 論理値 + 論理値 -> 加算
false + false; // 0

長整数の加算

js
// 長整数 + 長整数 -> 加算
1n + 2n; // 3n

// 長整数 + 数値 -> TypeError が発生
1n + 2; // TypeError: Cannot mix BigInt and other types, use explicit conversions

// 長整数を長整数以外に加算する場合は、どちらかのオペランドを変換する
1n + BigInt(2); // 3n
Number(1n) + 2; // 3

文字列の連結

js
// 文字列 + 文字列 -> 連結
"foo" + "bar"; // "foobar"

// 数値 + 文字列 -> 連結
5 + "foo"; // "5foo"

// 文字列 + 論理値 -> 連結
"foo" + false; // "foofalse"

// 文字列 + 数値 -> 連結
"2" + 2; // "22"

仕様書

Specification
ECMAScript Language Specification
# sec-addition-operator-plus

ブラウザーの互換性

BCD tables only load in the browser

関連情報