JavaScript/演算子
演算子(えんざんし、operator)とは、2 + 3の+のように、演算を表す記号のことです。2や3は被演算子(ひえんざんし、operand、オペランド)といいます。JavaScriptには算術演算子以外にもさまざまな演算子があります。変数の代入で使用した=も演算子の一種ですし、コンマ,も演算子の一種です。
目次 |
[編集] 算術演算子
- 数値も参照
加算 (+)、減算 (-)、乗算 (*)、除算 (/) の四則演算をはじめとする基本的な算術演算子が存在します。数値は常に浮動小数点数として扱われます。
| 演算子 | 意味 |
|---|---|
a + b |
加算 |
a - b |
減算 |
a * b |
乗算 |
a / b |
除算 |
a % b |
剰余 |
-a |
単項マイナス(算術否定) |
a++ または ++a |
インクリメント |
a-- または --a |
デクリメント |
[編集] 加算
加算演算子(かさんえんざんし、addition operator)は+です。
var two = 1 + 1; alert(two); // 2
[編集] 減算
減算演算子(げんざんえんざんし、げんさんえんざんし、subtraction operator)は-です。
var minus_one = 0 - 1; alert(minus_one); // -1
[編集] 乗算
乗算演算子(じょうざんえんざんし、じょうさんえんざんし、multiplication operator)は*です。
var four = 2 * 2; alert(four); // 4
[編集] 除算
除算演算子(じょざんえんざんし、じょさんえんざんし、division operator)は/です。
var one_half = 1 / 2; alert(one_half); // 0.5
ゼロ除算(ゼロじょざん、ゼロじょさん、division by zero)は例外ではなくNaNを返します。
alert( 0 / 0 ); // NaN
[編集] 剰余
剰余演算子(じょうよえんざんし、modulus operator)は%です。
やmod、rem、\、\\などではありません。割り算の余りを求めます。
var one = 10 % 3; alert(one); // 1
結果は必ず左オペランドの被除数(割られる数)と同じ符号になります。
var minus_one = -10 % 3; alert(minus_one); // -1
ゼロ剰余(ゼロじょうよ、modulo by zero)は例外ではなくNaNを返します。
alert( 0 % 0 ); // NaN
a % bはa - n * Math.floor(a / n)と等価です。
[編集] 単項マイナス
単項マイナス演算子(たんこうマイナスえんざんし、unary negation operator)は符号を反転させた数(反数)を返します。符号反転演算子(ふごうはんてんえんざんし)、算術否定演算子(さんじゅつひていえんざんし)などという言い方をする人もいます。
var one = 1; alert(-one); // -1
-aはa *= -1、すなわちa = a * -1と等価です。
[編集] インクリメント
インクリメント演算子(インクリメントえんざんし、increment operator)は変数の値を1増やします。
var x = 0; x++; alert(x); // 1
インクリメント演算子は後置++すると増やす前の値を返し、
var x = 0; var y = x++; alert(y); // 0 alert(x); // 1
++前置すると増やした後の値を返します。
var x = 0; var y = ++x; alert(y); // 1 alert(x); // 1
複数のインクリメント演算子を同時に適用することはできません。
var x = 0; (x++)++; // 構文エラー
x++はx += 1、すなわちx = x + 1と等価です。インクリメント演算子は変数の値を増加させるので、1++のようにリテラル(定数)に対して適用することはできません。
[編集] デクリメント
デクリメント演算子(デクリメントえんざんし、decrement operator)は変数の値を1減らします。
var x = 0; x--; alert(x); // -1
デクリメント演算子は後置--すると減らす前の値を返し、
var x = 0; var y = x--; alert(y); // 0 alert(x); // -1
--前置すると減らした後の値を返します。
var x = 0; var y = --x; alert(y); // -1 alert(x); // -1
複数のデクリメント演算子を同時に適用することはできません。
var x = 0; (x--)--; // 構文エラー
x--はx -= 1、すなわちx = x - 1と等価です。デクリメント演算子は変数の値を減少させるので、1--のようにリテラル(定数)に対して適用することはできません。
[編集] 冪乗
JavaScriptに**や^のような形をした冪乗演算子は存在しません。冪乗axを計算するにはMath.pow(a, x)を使用します。平方根はMath.sqrt(a)、(自然)対数はMath.log(x)です。
var power = Math.pow(2, 10); alert(power); // 1024
なお、^はビットごとのXOR演算子です。
[編集] ビット演算子
ビット演算子(ビットえんざんし、bitwise operator)とは、ビット演算の演算子です。ビット演算とは数値を二進法に直し、各ビットに対して行う演算のことです。
| 演算子 | 意味 |
|---|---|
a & b |
ビットごとのAND |
| b | ビットごとのOR |
a ^ b |
ビットごとのXOR |
~a |
ビットごとのNOT(補数) |
a << b |
左シフト |
a >> b |
符号維持右シフト |
a >>> b |
0埋め右シフト |
a >>> bは捨てられたビットの分だけ左から0を詰めます。ビット演算子は算術演算子よりも優先順位が低いことに注意してください。
[編集] 文字列連結演算子
+は加算演算子であると同時に、文字列連結演算子(もじれつれんけつえんざんし、string concatenation operator)でもあります。
var str = "Wiki" + "books"; alert(str); // "Wikibooks"
文字列と数値を連結すると、文字列の方が強いので数値は文字列に変換されます。
var str = "JavaScript " + 1.5; alert(str); // "JavaScript 1.5"
これは足し算をしようとして文字列がまじっていると厄介なことになります。
var one = "1"; var two = one + 1; alert(two); // "11" -- あれれ?
文字列の連結よりも数値の加算を優先させるには、文字列を数値に変換した上で加算しなければなりません。文字列を数値に変換するには、教科書的にはparseInt関数やparseFloat関数、Numberオブジェクトのコンストラクタなどを使いますが、
var one = "1"; var two = parseInt(one) + 1; alert(two); // 2
一般的には単項プラス演算子を使用した方が高速です。
var one = "1"; var two = +one + 1; alert(two); // 2
ほかにも1を掛ける (one * 1)、0を引く (one - 0)、0で0埋め右シフトをする (one >>> 0)、補数の補数を求める (~~one) などの方法があります。これらの演算子は数値にしか適用できないので、処理系が被演算子を自動的に数値に変換するためです。
[編集] 代入演算子
- 変数も参照
代入演算子(だいにゅうえんざんし、assignment operator)は変数に値を代入し、代入した値を返します。
var x; alert( x = 0 ); // "0" と警告
x = x + yのように自分自身に値を代入する演算は、x += yのように短縮表記することができます。たとえば、x *= yはx = x * yと等価です。
var x = 1; x += 1; // x = x + 1 alert(x); // 2
| 短縮表記 | 等価な表記 | 意味 |
|---|---|---|
x += y |
x = x + y |
加算代入 (assignment by addition) |
x -= y |
x = x - y |
減算代入 (assignment by subtraction) |
x *= y |
x = x * y |
乗算代入 (assignment by multiplication) |
x /= y |
x = x / y |
除算代入 (assignment by division) |
x %= y |
x = x % y |
剰余代入 (assignment by modulus) |
x <<= y |
x = x << y |
左シフト代入 (left shift assignment) |
x >>= y |
x = x >> y |
符号維持右シフト代入 (right shift assignment) |
x >>>= y |
x = x >>> y |
0埋め右シフト代入 (zero-fill right shift assignment) |
x &= y |
x = x & y |
ビットごとのAND代入 (bitwise AND assignment) |
x ^= y |
x = x ^ y |
ビットごとのXOR代入 (bitwise XOR assignment) |
x |= y |
x = x | y |
ビットごとのOR代入 (bitwise OR assignment) |
ただし、x = x && yと等価なx &&= yや、x = x || yと等価なx ||= yなどはありません。代わりにif ( x ) x = yやif ( !x ) x = yを使用してください。x += 1はx++と等価であり、x -= 1はx--と等価です。
[編集] 論理演算子
論理演算子(ろんりえんざんし、logical operator)とは、真の値を返す論理的な演算子です。短絡評価と副作用に注意してください。
| 演算子 | 意味 |
|---|---|
p && q |
論理AND(論理積、pかつq) |
p || q |
論理OR(論理和、pまたはq) |
!p |
論理NOT(否定、pでない) |
!(p && q)は(!p || !q)と等価であり、!(p || q)は(!p && !q)と等価です(ド・モルガンの法則)。論理XOR演算子は存在しませんが、
(p && !q) || (!p && q)(p || q) && (!p || !q)(p || q) && !(p && q)
などと表すことができます。
[編集] 比較演算子
比較演算子(ひかくえんざんし、comparison operator)とは、大小関係あるいは同値関係を比較して真偽値を返す演算子です。
| 演算子 | 意味 |
|---|---|
a < b |
より小さい(未満) |
a <= b |
より小さいか等しい(以下) |
a > b |
より大きい(超) |
a >= b |
より大きいか等しい(以上) |
a == b |
等しい |
a != b |
等しくない |
a === b |
厳密に等しい |
a !== b |
厳密に等しくない |
=<や=>のような変な比較演算子は存在しないので気をつけてください。必ず手前に大なり小なり、後にイコールが来ます。厳密な比較演算子は値が等しく、かつ型も等しい場合にtrueを返します。たとえば、1と "1" は等しい (1 == "1") ですが、厳密には等しくありません (1 !== "1")。
==演算子は被演算子に真偽値が含まれる場合は、それを数値に変換して比較します。たとえば、
Number(false); // 0 Number(true); // 1
なのでnull == falseはnull == 0に変換されfalseを返します。このことから、x == falseと!xは必ずしも等しい条件式にならないので注意してください(xがnullの場合、前者はfalse、後者はtrueを返す)。
==演算子は被演算子の一方が数値で他方が数値以外のオブジェクトの場合、他方を数値に変換して比較します。たとえば[] == ![]のような比較の場合、![]がfalseに変換されるので[] == falseになり、被演算子のfalseが0に変換されて[] == 0になり、被演算子の一方が数値の0なので他方の[]が数値に変換され、0 == 0になり、結果としてtrueになります。
[編集] メンバ演算子
メンバ演算子(メンバえんざんし、member operator、プロパティアクセサ、property accessor)とは、オブジェクトのプロパティまたはメソッドにアクセスするための演算子のことです。object.propertyの.がメンバ演算子です。さらに、object[property]の[]もメンバ演算子です。前者をドット記法、後者をブラケット記法といいます。
[編集] 特殊演算子
そのほかの特殊な演算子は特殊演算子(とくしゅえんざんし、special operator)と呼ばれます。一見すると演算子に見えないようなものも含まれます。
| 演算子 | 意味 |
|---|---|
condition ? ifTrue : ifFalse |
条件 |
value0, value1, ..., valueN |
コンマ |
delete object.property |
プロパティ削除 |
function name(param0, param1, ..., paramN){ statements } |
関数 |
get property name(){ statements } |
ゲッタ |
property in object |
プロパティ列挙、プロパティチェック |
instance instanceof object |
インスタンスチェック |
let variable |
ブロックスコープ変数宣言 |
new object() |
コンストラクト |
set property name(){ statements } |
セッタ |
this |
コンテキストオブジェクト |
typeof value |
データ型 |
void expression |
無効コンテキスト |
yield expression |
ジェネレータ |
[編集] typeof
typeof演算子(タイプオブえんざんし、typeof operator)はデータ型を返します。
typeof 42; // "number" typeof "Hello, world!"; // "string" typeof new Array(); // "array" 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++)++のように重ねて使用することができないため、結合性を定義しません。
- 練習
次の演算子の結合性をいえ。
typeof objectp == qok ? yes : noa, b, c
- 解答
- 右から左
typeof typeof objectはtypeof(typeof object)と解釈される。
- 左から右
p == q == rは(p == q) == rと解釈される。
- 右から左
ok0 ? yes0 : ok1 ? yes1 : no1はok0 ? yes0 : (ok1 ? yes1 : no1)と解釈される。
- 左から右
a, b, cは(a, b), cと解釈される。
[編集] 演算子の優先順位
| 優先順位 | 演算子 | 意味 | 結合性 | 項数 |
|---|---|---|---|---|
| 0 | . | メンバ | 左 | 2 |
| new | new | 右 | 1 | |
| 1 | () | 関数呼び出し | 左 | 1 |
| 2 | ++ | インクリメント | n/a | 1 |
| -- | デクリメント | n/a | 1 | |
| 3 | ! | 論理NOT | 右 | 1 |
| ~ | ビットごとのNOT | 右 | 1 | |
| + | 単項プラス | 右 | 1 | |
| - | 単項マイナス(算術否定) | 右 | 1 | |
| typeof | typeof | 右 | 1 | |
| void | void | 右 | 1 | |
| delete | delete | 右 | 1 | |
| 4 | * | 乗算 | 左 | 2 |
| / | 除算 | 左 | 2 | |
| % | 剰余 | 左 | 2 | |
| 5 | + | 加算 | 左 | 2 |
| - | 減算 | 左 | 2 | |
| 6 | << | 左シフト | 左 | 2 |
| >> | 右シフト | 左 | 2 | |
| >>> | 0埋め右シフト | 左 | 2 | |
| 7 | < | より小さい(未満) | 左 | 2 |
| <= | より小さいか等しい(以下) | 左 | 2 | |
| > | より大きい(超) | 左 | 2 | |
| >= | より大きいか等しい(以上) | 左 | 2 | |
| in | in | 左 | 2 | |
| instanceof | instanceof | 左 | 2 | |
| 8 | == | 等しい | 左 | 2 |
| != | 等しくない | 左 | 2 | |
| === | 厳密に等しい | 左 | 2 | |
| !== | 厳密に等しくない | 左 | 2 | |
| 9 | & | ビットごとのAND | 左 | 2 |
| 10 | ^ | ビットごとのXOR | 左 | 2 |
| 11 | | | ビットごとのOR | 左 | 2 |
| 12 | && | 論理AND | 左 | 2 |
| 13 | || | 論理OR | 左 | 2 |
| 14 | ?: | 条件 | 右 | 3 |
| 15 | = | 代入 | 右 | 2 |
| += | 加算代入 | 右 | 2 | |
| -= | 減算代入 | 右 | 2 | |
| *= | 乗算代入 | 右 | 2 | |
| /= | 除算代入 | 右 | 2 | |
| %= | 剰余代入 | 右 | 2 | |
| <<= | 左シフト代入 | 右 | 2 | |
| >>= | 右シフト代入 | 右 | 2 | |
| >>>= | 0埋め右シフト代入 | 右 | 2 | |
| &= | ビットごとのAND代入 | 右 | 2 | |
| ^= | ビットごとのXOR代入 | 右 | 2 | |
| |= | ビットごとのOR代入 | 右 | 2 | |
| 16 | , | コンマ | 左 | 2 |