読者です 読者をやめる 読者になる 読者になる

JavaScript勉強会

JavaScriptの学習日記

4.2 わかりやすく日時を表示する 《Dateオブジェクト》 【JavaScript超入門】

JavaScriptの学習メモ。

今日は『確かな力が身につくJavaScript「超」入門』の第4章を読んでみます。

 

jsstudy.hatenablog.com

 

 

4.2 Dateオブジェクト

(p.160)

この実習ではDateオブジェクトという、日時の取得・設定・計算をするオブジェクトを使用します。

今回は取得した日時を加工して、見慣れている12時間表記にしましょう。

Dateオブジェクトの利用方法と、取得したデータの加工がポイントです。

 

サンプルコード その1

まずは、普通に24時間表記の場合です。

以下の内容を「index.html」というファイル名で保存します。

 

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>4-02_12hour</title>
</head>
<body>
    <h1>わかりやすく日時を表示する</h1>
    <h2>年月日と日時を表示する</h2>
    <p>最終アクセス日時:<span id="time"></span></p>
    <script>
        var now = new Date();
        var year = now.getFullYear();
        var month = now.getMonth();
        var date = now.getDate();
        var hour = now.getHours();
        var min = now.getMinutes();

        var output = year + '/' + (month + 1) + '/' + date + ' ' + hour + ':' + min;
        document.getElementById('time').textContent = output;
    </script>
</body>
</html>

 

実行結果 その1

上記のHTMLファイルをブラウザーで開きます。

 

f:id:jsstudy:20170507130758p:plain

 

「13時3分」と表示されました。

 

サンプルコード その2

24時間表記を12時間表記に変換する処理を入れてみます。

以下の内容を「ampm.html」というファイル名で保存します。

 

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>4-02_12hour</title>
</head>
<body>
    <h1>わかりやすく日時を表示する</h1>
    <h2>12時間時計にしてみよう</h2>
    <p>最終アクセス日時:<span id="time"></span></p>
    <script>
        var now = new Date();
        var year = now.getFullYear();
        var month = now.getMonth();
        var date = now.getDate();
        var hour = now.getHours();
        var min = now.getMinutes();
        var ampm = '';
        if (hour < 12) {
            ampm = 'a.m.';
        } else {
            ampm = 'p.m.';
        }
        var output = year + '/' + (month + 1) + '/' + date + ' ' + (hour % 12) + ':' + min + ampm;
        document.getElementById('time').textContent = output;
    </script>
</body>
</html>

 

実行結果 その2

上記のHTMLファイルをブラウザーで開きます。

 

f:id:jsstudy:20170507131215p:plain

 

「13時4分」が「1:4p.m.」と変換されました。

 

Dateオブジェクト

(p.162)

Dateオブジェクトは日時を扱うためのオブジェクトです。次のようなことができます。

  1. 現在日時を取得する
  2. 過去や未来の日時を設定する
  3. 日時の計算をする

 

developer.mozilla.org

標準ビルトインオブジェクト > Date

日付や時刻を扱うことが可能な、JavaScript の Date インスタンスを生成します。

Date オブジェクトは、1970 年 1 月 1 日 (UTC) から始まるミリ秒単位の時刻値を基準としています。

 

Dateオブジェクトは初期化する必要がある

Dateオブジェクトは、メソッドとプロパティーを持っています。

Dateオブジェクトを使いたいとき、つまり日時の設定や計算をしたいときは、最初に初期化する必要があります。

 

var now = new Date();

このコードでは、Dateオブジェクトを初期化して、変数nowに代入しています。

 

初期化とは?

初期化(initialize)とは、利用可能な最初の状態にすることです。

 

f:id:jsstudy:20170507135031j:plain

(via On Your Mark, Get Set……Exercise Your Mind and Body!

 

初期化とは - IT用語辞典

初期化 しょきか 【 イニシャライズ 】 initialize

初期化とは、使用前の機器やソフトウェア、システムなどに操作や設定を行い、使用可能な初期状態にすること

 

製品の購入時、初使用時などに、最初に必要な設定情報の入力などを行う作業や処理などのことを指す場合と、電源投入時や再起動時などに、装置を初期状態に戻したり、制御ソフトを起動したり、保存された設定値を読み出して適用したりする処理などを指す場合がある。

 

コンピュータプログラムでは、プログラム内で利用するデータやオブジェクト、変数などを利用可能な初期状態にすることを初期化という。

宣言した変数に初期値を書き込む処理などが該当し、プログラムの冒頭や関数、メソッドの冒頭などで実行されることが多い。

 

new演算子とは?

「new」はオブジェクトを初期化するためのキーワードです。

 Dateオブジェクトをはじめとするいくつかのオブジェクトは、newを使って初期化してから使います。

 

developer.mozilla.org

 

new 演算子は、コンストラクタ関数を持ったユーザ定義のオブジェクト型または内蔵オブジェクト型のインスタンスを生成します。

 

コンストラクタ関数とは?

JavaScriptコンストラクター関数(constructor function)は、オブジェクトを初期化する特別な関数です。

 

コンストラクタ - JavaScript 入門

JavaScript のコンストラクタとは?

コンストラクタは、オブジェクトを作成し、初期化する関数オブジェクト (Function オブジェクト) です。

 

サイ本要約 9章 クラスとコンストラクタとプロトタイプ - noire722 の日記

 

コンストラクタ関数とは

  • オブジェクトのプロパティを初期化する関数
  • new演算子と一緒に使われる
  • オブジェクトの"クラス"を定義するにはコンストラクタ関数を定義するだけでよい
  • 通常、戻り値がない

 

JavaScript 第5版

JavaScript 第5版

 

(p.152) 9章 クラスとコンストラクタとプロトタイプ

9.1 コンストラクタ

var today = new Date();

 

new演算子の後に関数呼び出しを記述しています。

これで、新たにプロパティを持たないオブジェクトが生成され、そのオブジェクトをthisキーワードに代入して、指定した関数が呼び出されます。

このようにnew演算子と一緒に使うための関数を、コンストラクタ関数と呼びます。

コンストラクタ関数は、単にコンストラクタと呼ぶ場合があります。

コンストラクタの仕事は、新しく生成されたオブジェクトに対して、プロパティに値を設定するなどの初期化を行い、オブジェクトを使えるようにすることです。

 

JavaScript - オブジェクトを初期化する、とは(32485)|teratail

ベストアンサー 投稿 2016/04/16 11:53 raccy

 

「オブジェクトを初期化する」がどういう意味で使われているのか?結構難しい概念だと思います。一般的なプログラミングにおけるこの言葉を解説し、JavaScriptでどう当てはまるのかを説明していきたいと思います。

 

まずオブジェクト(object)とは何かです。プログラミング言語でオブジェクト(object)という単語を使う場合、何かしらのデータとして扱える物を意味します。一般的には変数に入れられる物がオブジェクトです。なお、これはオブジェクト指向には限りません。オブジェクト指向はこのオブジェクトを中心に考えてプログラミングをするというパラダイムであり、オブジェクト指向にしかオブジェクトが無いわけではありません。

 

オブジェクトは何らかのデータです。整数であったり、文字列だったり、配列であったり、関数であったり色々です。プログラムがオブジェクトを使うにあたってはじめにすることは、そのオブジェクト専用の領域を確保することです。これがオブジェクトの生成です。領域をどこにどう確保するのかはプログラミング言語によって様々ですが、この確保された領域は始めに何が入っているとおもいますか? 実はこれもプログラミング言語によって様々です。何も無い事を意味するnull値が入っていたりする場合もあれば、0のデータだったり、中にはメモリ上の前のデータ(ゴミ)がそのまま残っているというのもあります。意味が無いデータやゴミデータが入っていたりしたら、このままでは使おうと思っても使えません。

 

そこで必要になるのが初期化です。その領域をきちんと使えるように、期待している値で上書きしておく必要があります。これがオブジェクトを初期化すると言うことです。つまり、オブジェクトを使うには生成した後に初期化が必須なのです。初期化していないようなプログラムもありますが、いくつかの言語では、明示的に初期化を書かない場合は、特定の値(nullとか0とか)に自動で初期化してくれるようになっています。

 

では、JavaScirptに戻りましょう。JavaScriptはプロトタイプベースオブジェクト指向というちょっと変わったオブジェクト指向を採用しています(実用的に使われている他のプロトタイプベースオブジェクト指向言語Luaぐらいです)。JavaScriptではプロトタイプを元にオブジェクトを生成します。しかし、先ほど述べたとおり、生成しただけでは初期化がされていないため、使えません(JavaScriptでは{}という何もプロパティが入っていないオブジェクトが生成直後の状態です)。そこで初期化を行うために、プロトタイプ自身を関数として呼び出します。この初期化を行う関数部分コンストラクタと呼びます。こうして無事初期化されたオブジェクトを使用できます。

 

まとめますと、プロトタイプを使う、つまり、newするということは、そのプロトタイプを元にオブジェクトを生成し、プロトタイプ自体をコンストラクタとして扱って初期化すると言うことになります。

 

new コンストラクタ関数()
  1. new → オブジェクトを生成する
  2. コンストラクタ関数() → 生成したオブジェクトを初期化する

という2段階を経て、オブジェクトを使う準備をしているんですね?

 

「new Date()」と書いた場合、

  1. new → オブジェクトの生成を指示するnew演算子
  2. Date() → Dateオブジェクトのコンストラクタ関数で初期化する

という意味になりますね?

(内部的な挙動は知らないけど、構文上の意味は、こんなかんじでしょうか?)

 

  1. Dateオブジェクトは、生成された時点で、日時データを入れる箱になります。(この時点では、箱の中は空っぽ?)
  2. Dateオブジェクトは、初期化された時点で、現在の日時データがセットされます。(この時点で、箱の中に現在の日時データが入る?)

 

とりあえず、日時データを扱えればOKなので、Dateオブジェクトについては、この程度にしておきましょう。

(Dateオブジェクトの使い方で問題が生じたら、もっと深堀して調査すればOK)

 

Dateオブジェクトの使い方

Dateオブジェクトに用意されているメソッドを使って、年月日時分秒の数値を取得できます。

月は0から始まり、1ヶ月ずれてるので注意が必要ですね!(人間向けには+1で補正)

var now = new Date(); // 現在の日時のDateオブジェクト

var year = now.getFullYear(); // 年 (4桁の年数)
var month = now.getMonth();   // 月 (0-11)
var date = now.getDate();     // 日 (1-31)
var hour = now.getHours();    // 時 (0-23)
var min = now.getMinutes();   // 分 (0-59)
var sec = now.getSeconds();   // 秒 (0-59)

 

(参考)Dateオブジェクトについて、使い方のコツや注意点が紹介されてました。

 

iwb.jp

 

qiita.com

 

オブジェクトには初期化するものとしないものがある

(p.165)

オブジェクトの中には、Dateオブジェクトのように、使用するときにnewキーワードを使って「初期化」をするものがあります。

一方、4-4節で紹介するMathオブジェクトのやwindowオブジェクト、documentオブジェクトは初期化しません。

どうしてオブジェクトによって初期化したりしなかったりするのでしょうか?

実は、オブジェクトを初期化するかどうかには、次のような決まりがあります。

 

  • 複数のオブジェクトを作れるオブジェクトは初期化する
  • 複数のオブジェクトを作れないオブジェクトは初期化しない

 

●Dateオブジェクトは「複数作れる」

Dateオブジェクトをはじめとする、初期化が必要なオブジェクトには、メソッドとプロパティを持った「元オブジェクト」があります。

こうしたオブジェクトは、使用する際に、元オブジェクト の完全なコピーを作成して、そのコピーのほうを変数などに保存する(正確にはメモリに保存する)必要があります。

このコピー作業が「初期化」です。

Dateオブジェクトの元オブジェクトは1つしかありませんが、オブジェクトのコピーはいくつでも作ることができます。

 

図 「初期化」とは元オブジェクトをコピーすること

f:id:jsstudy:20170507192358p:plain

 

図 オブジェクトのコピーを複数作れるから、日付の計算ができる

f:id:jsstudy:20170507192415p:plain

 

コピーして、変数に保存したほうのDateオブジェクトは、持っているメソッドもプロパティも元のDateオブジェクトとまったく同じですが、それぞれに独自のプロパティ値を持つことができます。

そのため、基準日の違うDateオブジェクトを複数作成することができ、「未来の日付 - 現在の日付」のような計算ができるのです。

 

●Mathオブジェクトは「複数作れない」

一方、4-4節で紹介するMathオブジェクトはコピーを作ることができません。

Mathオブジェクトのプロパティはすべて読み取り専用で、書き換えることができないようになっていて、オブジェクトごとに独立のプロパティ値を持つ必要がありません。

そのため、Mathオブジェクトは元オブジェクトからコピーができず、複数のオブジェクトを作れないようになっているのです。

 

●windowオブジェクトやdocumentオブジェクトは?

それではwindowオブジェクトやdocumentオブジェクトはどうでしょう?

これらのオブジェクトは値を書き換えることもできますが、初期化はしません。

なぜなら、windowはブラウザウィンドウを指し、documentオブジェクトはそこに表示されているHTMLそのものを指しているからです。

ブラウザウィンドウやそのウィンドウに表示されるHTMLは1つしかなく、コピーを作れないようになっているのです。

 

JavaScriptは、他のクラスベースのオブジェクト指向プログラミング言語Javaなど)とは、随分と違った言語仕様になっているように思われます。

使っている用語は共通でも、中身は別物だと思ったほうが、無用な混乱を招かなくて済むかな?

 

JavaScriptのオブジェクトの機能についてもっと調べると、いろいろな機能が用意されていることが判明しました!

…とりあえずここでは、オブジェクトの初期化について、上記の説明のように理解しておきましょう。

 

(コンストラクタ関数には、new演算子を伴わないで、単独でも使う方法があるなど、ややこしい利用方法がありましたwww)

こういうところが「JavaScriptは分かりづらい」と言われる所以なのかもしれませんね(汗)

 

まとめ

  • Dateオブジェクトの使い方 → 「new Date();」と書く。
  • JavaScriptで元々用意されているオブジェクト(Dateオブジェクトなど)は、初期化して使う。
  • ただし、複製できないオブジェクトは、初期化しないでいきなり使える。(Mathオブジェクト、windowオブジェクト、documentオブジェクトなど)

 

JSのオブジェクトは、ややこしい使い方をしなければ、あまり悩まなくてOK?

(エラー上等!!! → 気軽に使ってみましょうw)