第1章 JavaScript言語仕様

演算子

演算子の概要

値を演算する記号を演算子と呼びます。演算子の中でもよく知られているのが、四則演算でも用いられる加算演算子( + )や減算演算子( - )などの算術演算子でしょう。

上記では+が加算演算子、その両側の変数xと、数字の5はオペランド(被演算子)といいます。オペランドとはリテラルや変数など、演算子の影響を受ける値のことです。

用語
演算子
変数やリテラルなどの値に対して演算を行うための記号です。
オペランド
演算の対象となる値。演算内容をあらわす記号は演算子と呼びます。例えば 10+X
という式では、10 と X がオペランドで、+ がオペレータです。

算術演算子

算術演算子は、数値に対して数学関数を実行します。

- 演算子( 単項演算子 ) -符号の反転

-演算子(単項演算子)はプラス・マイナスの符号を反転して返します。例えばxの値が-10の場合、-xは10を返します。

x = -10;

// xの値がマイナスなので、xの値は反転して10
-x;
出力結果

10

加算/減算/乗算/除算

加算、減算、乗算、除算演算子は数学の四則演算と記号もほぼ同じです。加算演算子はプラス記号( + )、減算演算子はマイナス記号( - )、乗算演算子はアスタリスク記号( * )、除算演算子はスラッシュ記号( / )です。

10 + 2;	// 加算
10 - 2;	// 減算
10 * 2;	// 乗算
10 / 2;	// 除算

※割る数が 0 だとオーバーフローのエラーが発生します。割る数が変数ならチェックしてから割り算を実行してください。

% 演算子 -剰余

剰余演算子( % )は割ったあまりを返します。

// 割り切れず、あまりの 2 が返される
10 % 4;

// 割り切れるから 0 が返される
10 % 2;

インクリメント/デクリメント

インクリメント( ++ )演算子は対象に1を加え、デクリメント( -- )演算子は対象から1を引きます

x = 5; 

// xは加算されて6
x++;
x; // 6が返される

y = 5;

// yは減算されて4
y--;
y; // 4が返される

インクリメント、デクリメント演算子は、オペランドの位置により処理のタイミングが変わります。演算子がオペランドの前にある場合は値を返す前に値を増減し、オペランドの後ろにある場合は値を返してから増減します

オペランドの後のインクリメント
x = 5;

// xは加算される前にzに代入されるので、zには5が代入される
z = x++;
出力結果

5

オペランドの前のインクリメント
x = 5;

// xの加算後にzに代入されるので、zには6が代入される
z = ++x;
出力結果

6

文字列演算子

+ 演算子は、左右どちらかのオペランドが文字列の場合、両方の文字列を連結します

x = "filename";

// x の値は filename.txt
x = x + ".txt";	

論理演算子

論理演算子はオペランドを真偽値として評価して、その結果をtrueかfalseで返します。論理演算子は主に制御構文で使われるため、論理演算子の使い方は制御構文で詳しく説明します。

論理演算子の一覧
演算子名称説明
&&論理積a && baとbがtrueならtrueを返します。
||論理和a || ba、もしくはbがtrueならtrueを返します。aがtrueの場合、bを評価しないでtrueを返します。
!論理否定! aaがtrueの場合はfalse、aがfalseの場合はtrueを返します。

&& 論理積演算子

&&演算子は演算する左右オペランドの両方が真であればtrue、どちらか一方でも偽であればfalseを返します

x = 10;

// xは5以上15未満か
x > 5 && x < 15;
出力結果

true

|| 論理和演算子

||演算子は左右オペランドのどちらか一方でも真があればtrue、どちらも偽であればfalseを返します。次の例では、左オペランドの条件式が偽ですが、右オペランドの条件式が真のため、||演算子はtrueを返します。

x = 10;

// xは5以上10未満か
x > 5 || x < 10;
出力結果

true

! 論理否定演算子

!演算子はオペランドの値をtrueかfalseの論理値で評価し、値を反転させます

x = false;

// xの値を反転
!x;
出力結果

true

x = 10;

// xの値を反転
!x;
出力結果

false

用語
論理積
&& 演算子は、演算する2つの値の両方が真であれば真、どちらか一方でも偽があれば偽を返します。
論理和
|| 演算子は、演算する2つの値のどちらか一方でも真があれば真となります。
論理否定
! 演算子は、値を反転させます。

比較演算子

比較演算子は値を比較する演算子です。比較演算子は左オペランドと右オペランドを比較し、その結果を true か false の論理値で返します。後で紹介するif文やfor文などの条件式に使われます。

比較演算子の一覧
演算子名称説明
==等値(等しい)左オペランドと右オペランドが等しければ true を返します。
!=不等値(等しくない)左オペランドと右オペランドが等しくなければ true を返します。
===同値(等しい)== 演算子と同様に比較を行いますが、比較対象が同じデータ型でないと評価しません。
!==非同値(等しくない)!= 演算子と同様に比較を行いますが、比較対象が同じデータ型でないと評価しません。
<小なり左オペランドが右オペランドより小さければ true を返します。
>大なり左オペランドが右オペランドより大きければ true を返します。
<=以下左オペランドが右オペランドと同じか小さければ true を返します。
>=以上左オペランドが右オペランドと同じか大きければ true を返します。

== 等値演算子

等値演算子( == )は左右オペランドを比較し、等しければtrue、等しくなければfalseを返します。

x = 10;
y = 10;
x == y;
出力結果

true

==演算子は比較する前に左右のオペランドを同じ型に変換するので、数値と文字列といった型が違っていても比較することができます。

// 等しい
1 == "1";
出力結果

true

意図しない挙動になる可能性があるので、可能な限り型の違いも評価する厳密等値演算子( === )を使うようにしてください。

!= 不等値演算子

不等値演算子( != )は等値演算子( == )と逆で、左右オペランドを比較し、等しければfalse、等しくなければtrueを返します。

x = 10;
y = 10;
x != y;
出力結果

false

!=演算子も==演算子と同様に型変換をするので、なるべく厳密不等値演算子( !== )を使うようにしてください。

=== 厳密等値演算子

厳密等値演算子( === )は等値演算子( == )と同様の比較を行いますが、比較対象が同じデータ型でないとfalseを返します。

1 === "1"; // ==演算子の場合は等しい
出力結果

false

数値の1と文字列の1を区別して比較したいときは === を使います。=== は同じデータ型でないと偽りを返します。

// 等しくない
1 === "1";
出力結果

false

数値や文字も、条件式として使われると真偽のどちらかの値として解釈されます。

// 0 は偽りなのでブロックを実行しない
if ( 0 ) { }

// 1 は真なのでブロックを実行
if ( 1 ) { }

// 空の文字列は偽なのでブロックを実行しない
if ( "" ) { }

// 通常の文字列なら真なのでブロックを実行する
if ( "a" ) { }

!== 厳密不等値演算子

厳密不等値演算子( !== )は不等値演算子( != )と同様の比較を行いますが、左右オペランドが等しくないか、比較対象が同じデータ型でなければtrueを返します。

1 !== "1";
出力結果

true

1 !== 1;
出力結果

false

< 小なり演算子

左オペランドが右オペランドより小さければtrueを返します。

10 < 20;
出力結果

true

> 大なり演算子

左オペランドが右オペランドより大きければtrueを返します。

10 > 20;
出力結果

false

<= 以下演算子

左オペランドが右オペランドと同じか小さければtrueを返します。

10 <= 20;
出力結果

true

>= 以上演算子

左オペランドが右オペランドと同じか大きければtrueを返します。

10 >= 20;
出力結果

false

ビット演算子

ビット演算子は、対象をビットの集合(0/1)として処理します。処理後、10進数表現の数値に変換して返します。

2進数

10進数は0から9の数字10個を使って数を表現しますが、2進数は数字の0と1の2個の数字を使います。
数字の0と1は2進数でも0と1で表せますが、数字の2は2進数の0と1の1桁では表せられません。そこで、もう1桁増やし、2桁の10(イチゼロ)で2を表します。10進数の10とは違い、2進数の10は1と0の組み合わせです。

// 数字の2を2進数に変換
x = 2;
x.toString(2);
出力結果

10

// 数字の3を2進数に変換
x = 3;
x.toString(2);
出力結果

11

// 数字の4を2進数に変換
x = 4;
x.toString(2);
出力結果

100

& ビット論理積演算子

ビット論理積演算子( & )は、左右のオペランドをビットごとに論理積をとって、その結果を返します。

1000 & 1001;
出力結果

1000

論理積(AND演算)は演算する2つの値の両方が真であれば真、どちらか一方でも偽があれば偽となります。
2進数の場合、どちらかの値が1でなければ結果は0になります。

| ビット論理和演算子

ビット論理和演算子( | )は、左右のオペランドをビットごとに論理和をとって、その結果を返します。

1000 | 1001;
出力結果

1001

論理和(OR演算)は演算する2つの値のどちらか一方でも真があれば真となります。
2進数の場合、どちらかの値が1であれば結果は1になります。

^ビット排他的論理和演算子

ビット排他的論理和演算子( ^ )は、左右のオペランドをビットごとに排他論理和をとって、その結果を返します。

1000 ^ 1001;
出力結果

1

排他的論理和(XOR演算)は演算する2つの値のどちらか一方でも真があれば真となりますが、両方とも真だと偽になります。
2進数の場合、どちらかの値が1であれば結果は1になりますが、両方とも1だと0になります。

~ ビット論理否定演算子

~ 演算子はオペランドの各ビットを反転させます。ビットが1の場合は0 、0の場合は1に反転します。

~ 1000;
出力結果

-1001

論理否定(NOT演算)は値を反転させます。
2進数の場合、値が1であれば結果は0になります。

<< 左シフト演算子
>> 右シフト演算子

左シフト演算子( << )は、左オペランドを右オペランドで示すビット数だけ、左にシフトした値を返します。

-1000 << 1;
出力結果

-2000

右シフト演算子( >> )は、左オペランドを右オペランドで示すビット数だけ、右にシフトした値を返します。

-1000 >> 1;
出力結果

-500

>>> ゼロ埋め右シフト演算子

ゼロ埋め右シフト演算子( >>> )は、オペランドの各ビットを指定されたビット数分だけ右へシフトします。

-1000 >>> 1;
出力結果

2147483148

>>> 演算子は、x の各ビットを y で指定されたビット数分だけ右へシフトします。上位ビットは、0 で埋められます。シフトされて最下位ビットより右へ移動した桁は破棄されます。

条件演算子

?: は、『条件演算子』です。? の前の引数が TRUE であれば、:
の前の引数が返されますが、FALSE であれば、: の後の引数が返されます。

x = a > b ? a : 0;

上記の例は、a が b より大きい値であれば a の値を返し、それ以外は 0 を返します。

代入演算子

代入演算子は、左辺の変数に右辺の値を代入します

// x に 10 を代入
x = 10;

= 演算子は単純代入演算子と呼ばれ、数学の = とは違い、右辺と左辺が同じという意味ではありません。そのため、次のような使い方は期待した結果にはなりません。

if ( x = 10 ){}

上記では、xと10が同じかどうかの条件式ではなく、x に 10 が代入されます。
そのため、x の値にかかわらず条件式は必ず true が返されます。数学の = と同じように、左オペランドと右オペランドを比較して、等しければ true を返すようにするには、等値演算子の == を使います。

if ( x == 10 ){}

代入演算子は代入と同時に演算処理を行うものもあります。

// x に 2 を加算
x = x + 2;

上記のように自分自身に演算を加えて代入したいケースでは、複合代入演算子を使って書き換えることができます。

// x に 2 を加算
x += 2;
+= 加算代入

加算して代入します。

 x = 10;  
 x += 2;  // xの値は12 
*= 乗算代入

乗算して代入します。

x = 10;
x *= 2; // x の値は 20 
-= 減算代入

減算して代入します。

 x = 10;
 x -= 2; // xの値は8 
/= 除算代入

除算して代入します。

 x = 10;
 x /= 2; // xの値は5
%= 剰余代入

剰余して代入します。

 x = 10;
 x %= 3; // xの値は1 
**= 累乗代入
x = 10;
x **= 2; // xの値は100 
&= ビット論理積代入
 x = 101;
 x &= 110; // xの値は100
|= ビット論理和代入
 x = 101;
 x |= 110; // xの値は111 
^= ビット排他的論理和代入
x = 101;
x ^= 110; // xの値は11 
<<= 左シフト代入
 x = 10; x <<= 2; // xの値は40
>>= 右シフト代入
x = 10;
x >>= 2; // xの値は2

x = -10;
x >>= 2; // xの値は-3 
>>>= ゼロ埋め右シフト代入
 x = 10;
x >>>= 2; // xの値は2
x = -10;
x >>>= 2; // xの値は1073741821 

カンマ演算子

カンマ演算子( , )は複数の式を記述するのに使われます

a=1, b=1, c=1, ...

for文(あとの章で解説します)で複数の変数を初期化したり、増減させたりしたいときに使えます。

// 下記では、変数 i と j を初期化し、i はインクリメント、j はデクリメントしています
for (var i = 0, j = 10; i <= 10; i++, j--){}

演算子の優先順位

JavaScriptをはじめほとんどのプログラミング言語には分数を直接表現する手段が無いので、除算演算子や浮動小数点数を使います。例えば2分の1という式をプログラミング言語の規則で表現すると、「1 / 2」、もしくは0.5となります。

いくつか例外がありますが、概ね代数学と同じ規則があてはまります。代数学と同様、演算子にも優先順位があり、加算演算子( + )や減算演算子( - )よりも、乗算演算子( * )、除算演算子( / )が優先されます。同一の優先順位にある演算子が複数並ぶときは、左から順に処理されます。

次の式では、「1 + 2」よりも乗算演算子が使われている「2 * 3」が先に計算されます。

1 + 2 * 3
出力結果

7

「1 + 2」を先に計算したい場合は、括弧を使います。計算式が複雑になるようなときは、積極的に括弧を使って可読性を高めましょう。

( 1 + 2 ) * 3
出力結果

9

次の表は演算子の優先順位が高い順で並べてあります。下段で詳しく説明していますが、演算子毎の結合性も記載しておきます。

演算子結合性
グループ化( () )しない
後置インクリメント( ++ )
後置デクリメント( -- )
しない
論理否定( ! )
ビット論理否定( ~ )
単項の +
単項の -
前置インクリメント( ++ )
前置デクリメント( -- )
累乗( ** )
乗算( * )
除算( / )
剰余( % )
加算( + )
減算( - )
左ビットシフト( << )
右ビットシフト( >> )
ゼロ埋め右シフト( >>> )
より小さい( > )
より小さいまたは等しい( >= )
より大きい( < )
より大きいまたは等しい( <= )
等値( == )
不等値( != )
同値( === )
非同値( !== )
ビット論理積( & )
ビット排他的論理和( ^ )
ビット論理和( | )
論理積( && )
論理和( || )
条件( ?: )
代入( = += -= など )
カンマ( , )

結合性

演算子には優先順位だけではなく、結合性という性質もあります。結合性は左右どちらかのオペランドを演算の対象にするか示します。左結合の場合、左から右に演算子を結合します。右結合の場合、右から左に演算子を結合します。

実例を挙げて少し詳しく説明しましょう。代入演算子は右結合です。次のコードであれば、xにaが代入されます。aにxが代入、ではありません。

x = a;

加算演算子( + )は左結合なので、次の式でいえばaにbを加算します。そのあと、右結合の代入演算子が加算結果をxに代入します。

// aにbを加算し、その結果をxに代入
x = a + b;

演算子のグループ

JavaScriptの演算子には、その性質により様々な種類とグループがあります。数値、文字列、ビットといった特定のオペランドに有効な演算子で分類すると、下記のようなグループに分かれます。

  • 算術演算子
  • 文字列演算子
  • 論理演算子
  • 比較演算子
  • ビット演算子
  • 代入演算子
  • カンマ演算子
  • 関係演算子

オペランドの種類による分類以外にも、必要とするオペランドの個数による分類もあります。
たとえば、演算子のほとんどは加算演算子のように2つのオペランドが必要です。

// 二項演算子
x + y;

数は多くありませんが、オペランドが1つだけのものや、3つのオペランドを必要とする演算子もあります。

// 単項演算子
delete obj;

// 三項演算子
(x==1) ? 1 : 0;

これらオペランドの個数により分類できるグループは下記の3つがあります。

  • 単項演算子
  • 二項演算子
  • 三項演算子

単項演算子

単項演算はオペランドを1つだけ取ります。インクリメント、デクリメント、論理否定や、+、- も単項演算子として使えます。

i++;
i--;
-i;

二項演算子

オペランド数によるグループ分けの中では最も数の多いグループです。加算、減算、乗算、除算などの算術演算子や、比較演算子、論理積、論理和などが二項演算子です。

// 加算
a + b;

// 大なり
a > b;

// 論理積
a && b;

三項(条件)演算子

オペランドを3つ取るので三項(条件)演算子と呼ばれます。クエスチョン( ? )の前のオペランドがtrueであれば、コロン( : )の前のオペランドが返され、falseであれば、コロン( : )の後のオペランドが返されます

x = a > b ? a : 0;

上記の例は、a が b より大きい値であれば a の値を返し、それ以外は 0 を返します。

算術演算子と比較演算子の併用

算術演算子と比較演算子は式の中で併用することができます。次の式はbに12を代入し、bが10と等価か比較しています。

a = ( ( b = 12 ) == 10 )
出力結果

false

上記の式は評価の結果falseが返され、右辺の変数aにfalseが代入されます。結果、出力結果がfalseになりました。

関連記事