プログラミング初心者向けのTypeScript入門連載の第4回はTypeScriptの式と演算について解説。TypeScriptでプログラミングへの理解を一歩深めよう。
前回は、TypeScriptのリテラルについて説明した。今回は、演算について基礎から説明していく。
これまで変数やリテラルについて見ながら、すでに簡単な演算についても取り扱ってきた。例えば、以下のようなコードを入力して実行すれば、価格を基に消費税を計算して、合計金額を表示できる。
var price, total, taxrate : number;
price = 1200; // (1)
taxrate = 0.08; // (2)
total = price * (1 + taxrate); // (3)
alert(total);
(1)と(2)は代入で、変数に値を入れている。(3)は若干複雑だが、加算と乗算を使って税込み価格を求めている。演算とは、広い意味で「計算すること」と考えていいが、変数に値を入れる代入も演算であることに注意しよう。また、演算に使う記号のことを「演算子」と呼ぶ。ここでは、「=」や「*」「+」が演算子だ。
もちろん、これだけではない。文字列を連結したり、クラスのメンバーを参照したりすることも演算である。クラスについてはまだ説明していないが、演算にはこういう例もあるということを確認するために、形式だけ見ておこう。
class Monster{
name:string; // 名前
hp:number; // 生命力
}
var aMonster: Monster = new Monster();
aMonster.name = "スライム"; // (1)
aMonster.hp = 10; // (2)
alert(aMonster.name + "(" + aMonster.hp + ")が現れた!"); // (3)
(1)と(2)では代入よりも、aMonsterとnameを区切る「.」に注目してほしい。「.」はクラスのメンバーを参照するための演算子である。上の例では、モンスターに含まれる名前(name)や生命力(hp)を利用するために使う、と考えればよい。ちなみに(1)の上の行にある「new」も演算子の1つであり、クラスのインスタンスを作成し、その参照を返す働きを持っている。
(3)では「+」という演算子が使われているが、これは最初に見たような数値の加算ではなく、文字列を連結するという働きを持つ。
最初に、「演算とは広い意味で計算すること」と述べたのは、いわゆる数学的な計算だけでなく、メンバーの参照や文字列の連結などさまざまな操作ができるからである。
なお、変数やリテラル、またそれらを演算子でつないだものを「式」と呼ぶ。式は値を返すのだが、それについては後で見ていくこととしよう。
数値の演算においては、加算や減算よりも乗算や除算が先に実行される。また、「()」で囲めば優先順位を高くできる。消費税の計算で、乗算よりも加算を先にやるために()を使っているのがその例だ。
この辺りの話は、中学校の数学で学んだ計算の順序と同じなので、分かりきった話だと思われるかもしれない。しかし、他の演算子も含めた話になると意外に奥が深い。後で、そういった興味深い例をいくつか挙げることとして、取りあえず、演算子の優先順位を表にまとめておく。ざっと目を通したら(全部覚える必要はない)、先に進もう。
優先順位 | 結合方向 | 演算子 | 説明 | |
---|---|---|---|---|
1 | → | . | メンバーの参照 | |
← | new | インスタンスの作成 | ||
2 | → | () | 関数呼び出し | |
3 | ++ -- |
インクリメント、デクリメント | ||
4 | ← | ! | 論理否定(NOT) | |
← | ~ | bitごとの論理否定(NOT) | ||
← | + - |
単項の+、-(符号の反転) | ||
← | typeof | オブジェクトの型 | ||
← | void | undefinedを返す | ||
← | delete | プロパティの削除 | ||
5 | → | * / % |
算術演算子(乗算、除算、剰余) | |
6 | → | + - |
算術演算子(加算、減算) | |
7 | → | << >> >>> |
ビットシフト | |
8 | → | < <= > >= |
比較演算子(大小関係) | |
→ | in | プロパティがあるかどうか | ||
→ | instanceof | ある型のインスタンスであるかどうか | ||
9 | → | == != === !== |
比較演算子(等しいかどうか) | |
10 | → | & | bitごとの論理積(AND) | |
11 | → | ^ | bitごとの排他的論理和(XOR) | |
12 | → | | | bitごとの論理和(OR) | |
13 | → | && | 論理積(AND) | |
14 | → | || | 論理和(OR) | |
15 | ← | ?: | 条件演算子 | |
16 | ← | yield | ジェネレーターの返す値 | |
17 | ← | = += -= *= /= %= <<= >>>>= >>>= &= ^= |= |
代入演算子 | |
18 | → | , | 後ろの式の値を返す | |
演算子の優先順位と結合方向(主なもの) |
見慣れない演算子も多いと思うが、初歩的なプログラミングにおいては、算術演算子、比較演算子、条件演算子、代入演算子をまず理解しておくといいだろう(ただし、比較演算子については注意点のみ後述し、条件演算子と併せて回をあらためて詳しく説明する)。
算術演算子に関しては、0で除算してしまうというトラブルに注意が必要だ。数学では、0で割ることは許されない。実際にやってみると、コンパイルエラーにはならないが、「Infinity」という結果になる。プログラムのミスで、除数が0になってしまうことがあると、それ以降の結果が正しく得られないので十分な注意が必要である。
var x, y: number;
x = 10;
y = x / 0;
alert(y);
Infinityとは「無限大」という意味です。数値の最大値(Number.MAX_VALUE)を超えた値はInfinityとなります。例えば、以下のようなプログラムを実行すると、Infinityと表示されます。
alert(Number.MAX_VALUE * 2);
なお、0/0の結果はInfinityではなくNaN(Not a Number=数値ではない値。不正な値を利用して数値演算が行われたことを示す値)となります。
算術演算子での注意点をもう1つ。TypeScript(JavaScript)にはべき乗の演算子はない。べき乗の計算をしたいときには、Mathクラスのpowメソッドを使う。以下の例では変数xの値を10乗した値を求めている。
var x, kib: number;
x = 2;
kib = Math.pow(x, 10);
alert(kib);
Visual Basicなどのプログラミング言語の経験がある人は、べき乗の演算子として「^」を使いたくなるかもしれないが、JavaScriptでは「^」はbitごとの排他的論理和を求める演算子なので、期待した結果は得られない。エラーになれば問題に気付くのだが、エラーにならないのでかえって厄介である。上の例で「x ^ 10」とすると、結果は8になってしまう(上の例では変数xの値は「2」である)。
bitごとの排他的論理和では、2進数で表された整数の同じ位置のbitが異なる場合だけ1になるので、図3のように「2 ^ 10」の結果は8になる。
Copyright© Digital Advantage Corp. All Rights Reserved.