連載
» 2014年08月05日 17時24分 UPDATE

TypeScriptで学ぶJavaScript入門:第4回 式と演算 (1/3)

プログラミング初心者向けのTypeScript入門連載の第4回はTypeScriptの式と演算について解説。TypeScriptでプログラミングへの理解を一歩深めよう。

[羽山博,著]
TypeScriptで学ぶJavaScript入門
Insider.NET

 

「TypeScriptで学ぶJavaScript入門」のインデックス

連載目次

 前回は、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 演算子の優先順位と演算の順序 図1 演算子の優先順位と演算の順序
  (1) 「*」よりも「+」を先に計算するために()で囲んだ。
  (2) priceに(1)の値を掛ける。
  (3) totalに(2)の値を代入する。

 この辺りの話は、中学校の数学で学んだ計算の順序と同じなので、分かりきった話だと思われるかもしれない。しかし、他の演算子も含めた話になると意外に奥が深い。後で、そういった興味深い例をいくつか挙げることとして、取りあえず、演算子の優先順位を表にまとめておく。ざっと目を通したら(全部覚える必要はない)、先に進もう。

優先順位 結合方向 演算子 説明
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とNaN

 Infinityとは「無限大」という意味です。数値の最大値(Number.MAX_VALUE)を超えた値はInfinityとなります。例えば、以下のようなプログラムを実行すると、Infinityと表示されます。

図2 数値として扱える最大値の2倍を求める 図2 数値として扱える最大値の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」である)。

図3 ^演算子による排他的論理和の計算 図3 ^演算子による排他的論理和の計算

 bitごとの排他的論理和では、2進数で表された整数の同じ位置のbitが異なる場合だけ1になるので、図3のように「2 ^ 10」の結果は8になる。

       1|2|3 次のページへ

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。