式と演算子

この章では JavaScript の式 (Expression) と、代入演算、比較演算、算術演算、ビット演算、論理演算、文字列演算、特殊演算の各演算子 (Operator) について説明します。

とは単一の値を決める、コードの妥当な単位です。

概念的に、式は 2 つの種類に分けることができます。ある値を変数に代入するものと、単純にある値を持つものです。例えば x = 7 という式は、x に 7 という値を代入する式です。この式自体の評価結果は 7 です。このような式では代入演算子を用います。一方 3 + 4 という式では、単純に評価結果が 7 になります。この式は代入を行いません。このような式で用いられる演算子は、単に演算子と呼ばれます。

JavaScript には、以下の種類の式があります:

  • 算術式: 評価結果は数値になります。例えば 3.14159 です。(一般に算術演算子を使用します)
  • 文字列式: 評価結果は文字列になります。例えば "Fred" や "234" です。(一般に文字列演算子を使用します)
  • 論理式: 評価結果は true または false になります。(よく論理演算子を用います)
  • オブジェクト式: 評価結果はオブジェクトになります。(評価結果をオブジェクトにするさまざまな例については、特殊演算子をご覧ください)

演算子

JavaScript では以下の種類の演算子を使用できます。このセクションでは演算子について説明します。また、演算子の優先順位にも触れます。

JavaScript には二項演算子と単項演算子、さらに唯一の特殊三項演算子である条件演算子があります。二項演算子は演算子の前後に 1 つずつ、計 2 つのオペランドが必要です:

operand1 operator operand2

例えば 3+4x*y です。

単項演算子は、演算子の前か後ろのどちらかに 1 つのオペランドが必要です:

operator operand

または

operand operator

例えば x++++x です。

代入演算子

代入演算子は右のオペランドの値に基づいて、左の変数に値を代入します。基本的な代入演算子は等号 (=) であり、これは右のオペランドの値を左のオペランドに代入します。すなわち x = y は、y の値を x に代入します。

他の代入演算子は、標準的な演算を行うための短縮表記です。次の表でそれを示します。

表 3.1 : 代入演算子
短縮表記した演算子 意味
x += y x = x + y
x -= y x = x - y
x *= y x = x * y
x /= y x = x / y
x %= y x = x % y
x <<= y x = x << y
x >>= y x = x >> y
x >>>= y x = x >>> y
x &= y x = x & y
x ^= y x = x ^ y
x |= y x = x | y

比較演算子

比較演算子はオペランドを比較して、その結果が真であるかに基づいて論理値を返します。オペランドには数値、文字列、論理値、オブジェクトを使用できます。文字列は Unicode を用いて、標準的な辞書順に基づいて比較されます。ほとんどの場合、2 つのオペランドが異なる型ならば JavaScript はそのオペランドを比較に適した型に変換しようとします (このルールの唯一の例外は === および !== であり、これらは "厳密に" 等値か否かを判断し、等値性をチェックする前にオペランドを適合する型に変換しません)。これは一般に、数値の比較が実行されることになります。次の表では比較演算子について、以下のコードを前提として説明します:

var var1 = 3, var2 = 4;
表 3.2 : 比較演算子
演算子 説明 true を返す例
等しい (==) オペランドが等しい場合に true を返します。 3 == var1
"3" == var1
3 == '3'
等しくない (!=) オペランドが等しくない場合に true を返します。 var1 != 4
var2 != "3"
厳密に等しい (===) オペランドが等しく、かつ同じ型である場合に true を返します。 3 === var1
厳密には等しくない (!==) オペランドが等しくなく、かつ/または同じ型でない場合に true を返します。 var1 !== "3"
3 !== '3'
より大きい (>) 左のオペランドが右のオペランドよりも大きい場合に true を返します。 var2 > var1
"12" > 2
以上 (>=) 左のオペランドが右のオペランド以上である場合に true を返します。 var2 >= var1
var1 >= 3
より小さい (<) 左のオペランドが右のオペランドよりも小さい場合に true を返します。 var1 < var2
"12" < "2"
以下 (<=) 左のオペランドが右のオペランド以下である場合に true を返します。 var1 <= var2
var2 <= 5

算術演算子

算術演算子はオペランドとして数値 (リテラルまたは変数) をとり、1 つの数値を返します。標準的な算術演算子は、加算 (+)、減算 (-)、乗算 (*)、除算 (/) です。これらの演算子は、他のほとんどのプログラミング言語で浮動小数点数を用いた場合と同じように機能します (0 で除算した結果は、NaN になることにも注意してください)。例えば:

console.log(1 / 2); /* 0.5 を表示 */
console.log(1 / 2 == 1.0 / 2.0); /* true になります */

さらに JavaScript では、以下の表で示す算術演算子も使用できます。

表 3.3 : 算術演算子
演算子 説明
%
(モジュロ)
二項演算子です。2 つのオペランドで除算したときの、整数の余りを返します。 12 % 5 は 2 を返します。
++
(インクリメント)
単項演算子です。オペランドに 1 を加えます。前置演算子 (++x) として用いた場合、オペランドに 1 を加えた後にその値を返します。後置演算子 (x++) として用いた場合、オペランドに 1 を加える前にその値を返します。 x が 3 のとき、++xx に 4 をセットして 4 を返します。一方、x++ は 3 を返して x に 4 をセットします。
--
(デクリメント)
単項演算子です。オペランドから 1 を引きます。戻り値はインクリメント演算子のものと同様です。 x が 3 のとき、--xx に 2 をセットして 2 を返します。一方、x-- は 3 を返して x に 2 をセットします。
-
(符号反転)
単項演算子です。オペランドの符号を反転して、その値を返します。 x が 3 のとき、-x は -3 を返します。

ビット演算子

ビット演算子はそのオペランドを 10 進数や 16 進数や 8 進数ではなく、32 ビットの集合 (0 と 1) として扱います。例えば、10 進数の 9 の 2 進表現は 1001 です。ビット演算子はこのように 2 進表現にした上で演算を行いますが、標準の JavaScript の数値を返します。

次の表で JavaScript のビット演算子について説明します。

表 3.4 : ビット演算子
演算子 使用法 説明
ビットごとの AND a & b オペランドの対応するビットがともに 1 である各ビットについて 1 を返します。
ビットごとの OR a | b オペランドの対応するビットがどちらかまたはともに 1 である各ビットについて 1 を返します。
ビットごとの XOR a ^ b オペランドの対応するビットがどちらか一方のみ 1 である各ビットについて 1 を返します。
ビットごとの NOT ~ a オペランドの各ビットを反転します。
左シフト a << b 2 進表現の ab ビット分だけ左にシフトします。右から 0 を詰めます。
符号を維持した右シフト a >> b 2 進表現の ab ビット分だけ右にシフトします。溢れたビットは破棄します。
0 埋め右シフト a >>> b 2 進表現の ab ビット分だけ右にシフトします。溢れたビットは破棄し、左から 0 を詰めます。

ビットごとの論理演算子

概念的にビットごとの論理演算子は、以下のように機能します:

  • オペランドは 32 ビット整数に変換され、ビット (0 と 1) の列として表現されます。
  • 第 1 のオペランドの各ビットは第 2 のオペランドの対応するビットと対にされます。第 1 ビットと第 1 ビット、 第 2 ビットと第 2 ビット、というように対にされます。
  • 演算子は各ビットのペアに適用され、結果はビットごとに組み立てられます。

例えば 9 の 2 進表現は 1001 で、15 の 2 進表現は 1111 です。ここで、ビット演算子がこれらの値に適用されたときの結果は、以下のようになります:

表 3.5 : ビット演算子の例
演算式 結果 2 進数での説明
15 & 9 9 1111 & 1001 = 1001
15 | 9 15 1111 | 1001 = 1111
15 ^ 9 6 1111 ^ 1001 = 0110
~15 0 ~1111 = 0000
~9 6 ~1001 = 0110

ビットシフト演算子

ビットシフト演算子は 2 つのオペランドをとります。第 1 のオペランドはシフトされる数を指定し、第 2 のオペランドは、第 1 のオペランドをシフトさせるビット数を指定します。シフト演算の方向は使用する演算子によって決まります。

シフト演算子はそのオペランドを 32 ビット整数に変換し、左のオペランドと同じ型で結果を返します。

シフト演算子は次の表のとおりです。

表 3.6 : ビットシフト演算子
演算子 説明
<<
(左シフト)
この演算子は、第 1 オペランドを指定したビット数分だけ左にシフトします。左に溢れたビットは破棄されます。0 のビットを右から詰めます。 9<<2 の結果は 36 になります。1001 を 2 ビット左にシフトすると 100100 になり、これは 36 であるためです。
>>
(符号を維持した右シフト)
この演算子は、第 1 オペランドを指定したビット数分だけ右にシフトします。右に溢れたビットは破棄されます。左端のビットのコピーを左から詰めます。 9>>2 の結果は 2 になります。1001 を 2 ビット右にシフトすると 10 であり、これは 2 であるためです。同様に、-9>>2 の結果は、符号が維持されるため -3 になります。
>>>
(0 埋め右シフト)
この演算子は、第 1 オペランドを指定したビット数分だけ右にシフトします。右に溢れたビットは破棄されます。0 のビットを左から詰めます。 19>>>2 の結果は 4 になります。10011 を 2 ビット右にシフトすると 100 であり、これは 4 であるためです。非負数では、0 埋め右シフトと符号を維持した右シフトは同じ結果になります。

論理演算子

論理演算子では、基本的に真偽 (論理) 値を用います。そのような値があると真偽値を返します。しかし && および || 演算子は、実際には指定されたオペランドの一方の値を返します。そのため、非真偽値とともに論理演算子が使われると非真偽値を返します。論理演算子について、次の表で説明します。

表 3.6 : 論理演算子
演算子 使用法 説明
&& expr1 && expr2 (論理 AND) expr1 を false と見ることができる場合は、expr1 を返します。そうでない場合は expr2 を返します。したがって真偽値を用いた場合、両オペランドが true であれば && は true を返し、そうでなければ false を返します。
|| expr1 || expr2 (論理 OR) expr1 を true と見ることができる場合は、expr1 を返します。そうでない場合は expr2 を返します。したがって真偽値を用いた場合、どちらかのオペランドが true であれば || は true を返し、両方とも false であれば false を返します。
! !expr (論理 NOT) 単一のオペランドを true と見ることができる場合は、false を返します。そうでない場合は true を返します。

false と見ることができる式とは、null、0、空文字列 ("")、または undefined に評価される式のことです。

以下のコードで && (論理 AND) 演算子の例を示します。

var a1 =  true && true;     // t && t は true を返す
var a2 =  true && false;    // t && f は false を返す
var a3 = false && true;     // f && t は false を返す
var a4 = false && (3 == 4); // f && f は false を返す
var a5 = "Cat" && "Dog";    // t && t は Dog を返す
var a6 = false && "Cat";    // f && t は false を返す
var a7 = "Cat" && false;    // t && f は false を返す

以下のコードで || (論理 OR) 演算子の例を示します。

var o1 =  true || true;     // t || t は true を返す
var o2 = false || true;     // f || t は true を返す
var o3 =  true || false;    // t || f は true を返す
var o4 = false || (3 == 4); // f || f は false を返す
var o5 = "Cat" || "Dog";    // t || t は Cat を返す
var o6 = false || "Cat";    // f || t は Cat を返す
var o7 = "Cat" || false;    // t || f は Cat を返す

以下のコードで !(論理 NOT) 演算子の例を示します。

var n1 = !true;  // !t は false を返す
var n2 = !false; // !f は true を返す
var n3 = !"Cat"; // !t は false を返す

ショートサーキット評価

論理式は左から右に評価されるため、以下のルールを用いることで "ショートサーキット" 評価ができるようになっています:

  • false && anything は false にショートサーキット評価します。
  • true || anything は true にショートサーキット評価します。

論理のルールは、これらの評価が常に正確であることを保証しています。上記の式で anything の部分は評価されないため、このようにしても副作用が生じないことに注意してください。

文字列演算子

比較演算子は文字列に使用できますが、これに加えて 2 つの文字列を結合する結合演算子 (+) も使用でき、これは 2 つのオペランドの文字列を結合した文字列を返します。例えば、"my " + "string""my string" という文字列を返します。

短縮表記した代入演算子 += も文字列の結合に使用できます。例えば、変数 mystring に "alpha" という値が格納されているとき、式 mystring += "bet" の評価結果は "alphabet" となり、この値を mystring に代入します。

特殊演算子

JavaScript には、以下の特殊演算子があります。

条件演算子

条件演算子は JavaScript では唯一の、3 つのオペランドをとる演算子です。演算子は条件に基づいて、2 つの値のうち 1 つを選択します。構文は以下のとおりです:

condition ? val1 : val2

condition が true の場合、演算子は val1 の値を選択します。そうでない場合は val2 の値を選択します。標準的な演算子が使用できる場所ならどこででも、条件演算子を使用できます。

例えば、

var status = (age >= 18) ? "adult" : "minor";

この文では、age が 18 以上の場合に "adult" という値を変数 status に代入します。そうでない場合は、"minor" という値を status に代入します。

コンマ演算子

コンマ演算子 (,) は単に両側のオペランドを評価し、第 2 のオペランドの値を返します。この演算子は主に for ループ内で使用されます。このことで、ループのたびに複数の変数を更新できます。

例えば、a は一辺が 10 要素の 2 次元配列であるとき、以下のコードではコンマ演算子を用いて 2 変数を同時にインクリメントしています。このコードでは配列の対角成分の値を出力します:

for (var i = 0, j = 9; i <= 9; i++, j--)
  document.writeln("a[" + i + "][" + j + "]= " + a[i][j]);

delete

delete 演算子はオブジェクトやオブジェクトのプロパティ、配列の指定されたインデックスの要素を削除します。構文は以下のとおりです:

delete objectName;
delete objectName.property;
delete objectName[index];
delete property; // with 文内でのみ有効

ここで objectName はオブジェクトの名前を、property は既存のプロパティを、index は配列の要素の位置を示す整数をそれぞれ表しています。

4 番目の形式は with 文内でのみ有効で、これはあるオブジェクトからプロパティを削除します。

delete を用いて暗黙的に宣言された変数を削除できますが、var 文で宣言された変数は削除できません。

delete 演算が成功すると、そのプロパティや要素には undefined がセットされます。また、演算が可能である場合に delete 演算子は true を返します。演算が不可能である場合は false を返します。

x = 42;
var y = 43;
myobj = new Number();
myobj.h = 4;    // プロパティ h を作成
delete x;       // true を返す (暗黙的に定義された場合は削除可)
delete y;       // false を返す (var つきで宣言された場合は削除不可能)
delete Math.PI; // false を返す (定義済みプロパティは削除不可能)
delete myobj.h; // true を返す (ユーザ定義プロパティは削除可能)
delete myobj;   // true を返す (暗黙的に宣言された場合は削除可能)
配列要素の削除

配列の要素を削除したとき、配列の長さは影響を受けません。例えば a[3] を削除したとき、a[4] は依然 a[4] のままで、a[3] は undefined になります。

delete 演算子で配列要素を除去すると、もうその要素は配列からなくなります。次の例で trees[3]delete によって除去されます。しかし、trees[3] は依然指し示すことが可能であり、undefined を返します。

var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
delete trees[3];
if (3 in trees) {
  // この部分は実行されません
}

配列要素は存在させたいが値は未定義にしたい場合は、delete 演算子の代わりに undefined キーワードを使用してください。次の例では trees[3]undefined という値が代入されますが、その配列要素は存在したままになります:

var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
trees[3] = undefined;
if (3 in trees) {
  // この部分は実行されます
}

in

in 演算子は、指定されたプロパティが指定されたオブジェクトにある場合に true を返します。構文は以下のとおりです:

propNameOrNumber in objectName

ここで propNameOrNumber はプロパティ名または配列のインデックスを表す文字列式または数値式を、objectName はオブジェクトの名前をそれぞれ表します。

次の例で in 演算子の使用法を示します。

// 配列
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees;        // true を返す
3 in trees;        // true を返す
6 in trees;        // false を返す
"bay" in trees;    // false を返す (インデックスの指す値ではなく、
                   // インデックスの数字を指定しなければならない)
"length" in trees; // true を返す (length は Array のプロパティ)

// 定義済みオブジェクト
"PI" in Math;          // true を返す
var myString = new String("coral");
"length" in myString;  // true を返す

// ユーザ定義オブジェクト
var mycar = {make: "Honda", model: "Accord", year: 1998};
"make" in mycar;  // true を返す
"model" in mycar; // true を返す

instanceof

instanceof 演算子は、指定されたオブジェクトが指定されたオブジェクトの種類である場合に true を返します。構文は以下のとおりです:

objectName instanceof objectType

ここで objectNameobjectType と比較するオブジェクトの名前を、objectTypeDateArray のようなオブジェクトの種類をそれぞれ表します。

実行時にオブジェクトの種類を確認する必要があるときは instanceof を使用してください。例えば例外を受け取るとき、発生した例外の種類に応じて、別々の例外を扱うコードに分岐することができます。

例えば次のコードでは、instanceof を使用して theDayDate オブジェクトであるかを判断しています。theDayDate オブジェクトであるため、if 文の中の文は実行されます。

var theDay = new Date(1995, 12, 17);
if (theDay instanceof Date) {
  // 実行される文
}

new

new 演算子は、ArrayBooleanDateFunctionImageNumberObjectOptionRegExpString といった定義済みオブジェクトやユーザ定義オブジェクトのインスタンス作成に使用します。サーバでは DbPoolLockFileSendMail といったオブジェクトの使用できます。new の使用法は以下のとおりです:

var objectName = new objectType([param1, param2, ..., paramN]);

オブジェクト初期化子を使用してオブジェクトを作成することもできます。オブジェクト初期化子の使用にて説明しています。

詳しくはコア JavaScript リファレンスの new 演算子のページを参照してください。

this

this を使用することでカレントオブジェクトを参照できます。一般に this は、あるメソッド内でそのメソッドを呼び出したオブジェクトを参照します。this の使用法は以下のとおりです:

this["propertyName"]
this.propertyName

例 1
あるオブジェクトの value プロパティの妥当性を確認する、validate という関数を想定します。関数にはオブジェクトと上限および下限の値を渡します:

function validate(obj, lowval, hival){
  if ((obj.value < lowval) || (obj.value > hival))
    alert("Invalid Value!");
}

各フォーム要素の onChange イベントハンドラにおいて validate を呼び出します。this を用いてフォーム要素を渡すことができます。次の例をご覧ください:

<B>Enter a number between 18 and 99:</B>
<INPUT TYPE="text" NAME="age" SIZE=3
   onChange="validate(this, 18, 99);">

例 2
form プロパティと組み合わせると、this でカレントオブジェクトの親のフォームを参照できます。次の例では、myForm フォームというフォームに Text オブジェクトとボタンが格納されています。ユーザがボタンをクリックすると、Text オブジェクトの値にフォーム名がセットされます。ボタンの onClick イベントハンドラは this.form を利用して親のフォームである myForm を参照します。

<FORM NAME="myForm">
Form name:<INPUT TYPE="text" NAME="text1" VALUE="Beluga">
<P>
<INPUT NAME="button1" TYPE="button" VALUE="Show Form Name"
   onClick="this.form.text1.value = this.form.name;">
</FORM>

typeof

typeof 演算子は次の方法のうち、どちらかの方法で使用します:

  1. typeof operand
    
  2. typeof (operand)
    

typeof 演算子は、未評価のオペランドの型を指す文字列を返します。operand は返される型を調べる対象となる文字列、キーワード、オブジェクトです。括弧はあってもなくてもかまいません。

以下の変数を定義することを想定します:

var myFun = new Function("5 + 2");
var shape = "round";
var size = 1;
var today = new Date();

typeof 演算子は、変数の型に応じて以下の値を返します:

typeof myFun;     // "function" を返す
typeof shape;     // "string" を返す
typeof size;      // "number" を返す
typeof today;     // "object" を返す
typeof dontExist; // "undefined" を返す

truenull というキーワードに対して、typeof 演算子は以下の結果を返します:

typeof true; // "boolean" を返す
typeof null; // "object" を返す

数値や文字列に対して、typeof 演算子は以下の結果を返します:

typeof 62;            // "number" を返す
typeof 'Hello world'; // "string" を返す

プロパティ値に対して、typeof 演算子はプロパティが持つ値の型を返します:

typeof document.lastModified; // "string" を返す
typeof window.length;         // "number" を返す
typeof Math.LN2;              // "number" を返す

メソッドや関数に対して、typeof 演算子は以下の結果を返します:

typeof blur;        // "function" を返す
typeof eval;        // "function" を返す
typeof parseInt;    // "function" を返す
typeof shape.split; // "function" を返す

定義済みオブジェクトに対して、typeof 演算子は以下の結果を返します:

typeof Date;     // "function" を返す
typeof Function; // "function" を返す
typeof Math;     // "object" を返す
typeof Option;   // "function" を返す
typeof String;   // "function" を返す

void

void 演算子は次の方法のうち、どちらかの方法で使用します:

  1. void (expression)
    
  2. void expression
    

void 演算子は、値を返さずに評価する式を指定します。expression は、評価する JavaScript の式です。式の周りの括弧はあってもなくてもかまいませんが、使用する方が見た目がよいです。

void 演算子を使用することで、式をハイパーテキストリンクとして指定できます。式は評価されますが、開いている文書の代わりに読み込まれることはありません。

以下のコードは、ユーザがクリックしても何も起こらないハイパーテキストリンクを作成します。ユーザがリンクをクリックすると void(0) は undefined になり、JavaScript としては影響を及ぼしません。

<A HREF="javascript:void(0)">Click here to do nothing</A>

以下のコードは、ユーザがクリックするとフォームが送信されるハイパーテキストリンクを作成します。

<A HREF="javascript:void(document.form.submit())">
Click here to submit</A>

演算子の優先順位

演算子の precedence は、式を評価する際に演算子を適用する順番を定義します。括弧を用いて、演算子の優先順位を上書きできます。

次の表では演算子の優先順位を、高いものから低いものの順に並べています。

関連する議論に従って、この表は演算子の優先順位が高い順にひっくり返されています。

表 3.7 : 演算子の優先順位
演算子の種類 個々の演算子
メンバ . []
インスタンスの呼び出し/作成 () new
否定/インクリメント ! ~ - + ++ -- typeof void delete
乗算/除算 * / %
加算/減算 + -
ビットシフト << >> >>>
関係 < <= > >= in instanceof
等価 == != === !==
ビットごとの and &
ビットごとの xor ^
ビットごとの or |
論理積 &&
論理和 ||
条件 ?:
代入 = += -= *= /= %= <<= >>= >>>= &= ^= |=
コンマ ,

この表の詳細版に関してはリファレンスのセクションを参照してください。

Document Tags and Contributors

Contributors to this page: akiroom, ethertank, Electrolysis, yyss, syar, Potappo
最終更新者: ethertank,