JavaScriptで数値を扱う「Number」、数値計算を扱う「Math」、日付を扱う「Date」の基本JavaScript標準ライブラリの使い方超入門(4)(2/4 ページ)

» 2016年10月18日 05時00分 公開
[金城俊哉]

JavaScriptで三角関数って、いったい誰が使うんです?( 数学的な演算処理)

 Mathオブジェクトは、数値演算を行うためのオブジェクトです。Numberは「数値型の値を直接操作する」ためのラッパーオブジェクトでしたが、Mathオブジェクトは数値を操作するのではなく「数値演算を行うオブジェクト」です。指数計算や平方根、三角関数などの数学にかかわる演算を行うメソッドが用意されています。

静かなるプロパティとメソッド?

 Mathオブジェクトのすべてのプロパティやメソッドは、静的です。これは寡黙なメソッドを意味しているのではなく、「動」に対する「静」を表しています。

Driver

「いかにも難解なプログラミング本のような抽象的な表現ですねぇ」


Navigator

「端的にいえば、静的プロパティや静的メソッドというものは、『インスタンスを生成しなくても使える』のです。つまり、new演算子でインスタンスを作らなくてもすぐに使えるのですね」


Driver

「そういえばオブジェクト指向言語では、そういったオブジェクトがなくても使える、いわば手続き指向的なプログラミングができる場合がありますね」


Navigator

「例えばですよ、数値を四捨五入するround()メソッドは、次のように書けば、『1.5』の小数点以下を四捨五入した整数の値を返してくれます」


var num = Math.round(1.5);
Driver

「でもこのMathってオブジェクトですよ。結局オブジェクトを使ってますよね」


Navigator

「Mathはビルトインのオブジェクトです。確かにMathオブジェクトのインスタンスを使用していますが、事前にnewでインスタンス化してませんよね。Mathオブジェクトは『インスタンスを1個しか生成しないオブジェクト』なのです。つまり『Math.〜』と書けば自動的にインスタンスが1個だけ用意されます」


Driver

「続けて別のところでMathオブジェクトのメソッドを使った場合はどうなるんです? 別のインスタンスが生成されるってことはないんですか?」


Navigator

「あくまで1個のインスタンスしか生成されませんから、その場その場で別々のインスタンスが生成されることはありません」


Driver

「あくまで1個のインスタンスだけなんですね。オブジェクトから複数のインスタンスを生成して個別に処理を行うことはできないわけですね」


Navigator

「そもそも数学的な演算処理というのは『与えられた値を演算して結果を返す』ことを行えばいいですよね。いわば『その場限りの処理』を行えばよいので、インスタンスが1個あれば十分です。メソッドが呼び出されるたびに、このインスタンスからメソッドを実行して値を返せば済むわけですから


Driver

「『オブジェクトからインスタンスを生成してメソッドを実行する』のではなく『直接、オブジェクトで定義されているメソッドを呼び出せる』と考えればいいんですね」


Navigator

「このようなことから、次のようにnew演算子を使用して明示的にインスタンスを生成することはできません」


インスタンス化することはできない

いざ、数値演算

Navigator

「目的順に各プロパティとメソッドを実行してみましょう」


Driver

「結果は、文の横にコメントとして記載しておきました」


演算処理を実行(math.html)

Onepoint writeln()メソッド

 今回は画面に書き出す内容がたくさんあるので、write()メソッドではなく、書き出したあとに改行を行うwriteln()メソッドを使用します。ただし、このメソッドで改行を行っても「HTMLドキュメントの中で改行が行われるだけ」なので、画面には改行ではなく半角スペースとして表示されます。

 そこで、<script>〜</script>全体を<pre>〜</pre>タグで囲むようにします。preは「整形済みテキスト(preformatted text)であることを示す要素で、この要素内の空白文字や改行は、そのままブラウザーの画面に反映されるようになります。

&lt;pre&gt;〜&lt;/pre&gt;を使用

Memo なぜ静的メソッドやプロパティはインスタンスがなくても使えるのか

 静的プロパティや静的メソッドは、new演算子でインスタンスを生成しなくてもすぐに使えます。本編でも取り上げたround()メソッドは、次のように書けば「1.5」の小数点以下を四捨五入した整数の値を返してくれます。

var num = Math.round(5.5);

 Mathオブジェクトのインスタンスは生成していません。代わりに「Math.round(1.5)」と書いていますね。これは「何.どうする」の書き方で、普通であれば「何」の部分はオブジェクトのインスタンス(の参照変数)名を書きますよね。ところが、ここではMathオブジェクトそのものの名前を書いています。これはいったいどういうことなのでしょう。

 結論からいうとMathは「最初から1個だけインスタンスを持っている」オブジェクトなのです。つまり、「Math.ナントカ」と書けば自動的にインスタンスが1個だけ用意されるのですね。それでインスタンスを生成する必要はなく、代わりにオブジェクトの名前である「Math」と「.」をメソッド名の前に書けばメソッドが実行されるというわけなのです。

Mathの自動的に作成されたインスタンス.round(5.5)

 このように、静的メソッドやプロパティはインスタンスを必要としないのではなく「最初から1つだけ用意されているインスタンスから実行される」というわけなのです。

 しかし、そもそも何でインスタンスを自動的に作るのか、それもなぜ1個しか作らないのか、という疑問もありますよね。

 そもそも数値の演算処理というのは、何かの値を使って演算して結果を返すことです。ということは、インスタンスを1個だけ作っておいて、メソッドが呼ばれたらこのインスタンスに値を入れて演算して結果を返せばそれで終わりです。次にメソッドが呼ばれたらインスタンスの中身を書き換えて演算して結果を返す、という具合にするだけです。

 演算結果は、メソッドを呼び出した側で変数に代入するとか、画面に表示するとかの処理を行っていますので、前の演算結果をインスタンスで保持することに意味はありませんよね。

 こういうわけで数値の演算を行うオブジェクトには、「インスタンスが1個あればOK」なのです。動的にインスタンスを生成するのではなく、「呼び出された時点でインスタンスが用意される」ことから、静的という言葉が使われているということなのですね。


Tips 0から9までの乱数を発生させてみよう

 random()メソッドを使うと、乱数を発生させることができます。乱数なんて何に使うのか不思議に思いますが、ゲームなどでよく使われます。例えば「おみくじアプリ」では8以上の値が出たら「大吉」と表示するという具合です。

 なお、random()メソッドは0.0から1.0未満の値を返すので、まずはこれを10倍してからfloor()メソッドで小数点以下を切り捨てるようにすることで0から9までのランダムな整数を取得するようにしたいと思います。

random()メソッドが返した乱数を10倍してからfloo()メソッドで小数点以下を切り捨てる

 次のようにfor文を使って、0〜9までのランダムな値を10回、出力してみます。

0〜9までのランダムな値を10回出力する(random.html)
実行結果

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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