今日は何曜日?…getDay()の値は0~6
値がある数値の範囲になる場合は、if~else文、switch文ではなく配列インデックスにすると便利、というお話しです
サンプル:「今日は○曜日です」を表示するプログラム
「今日は○曜日です」
javascriptが無効になっています。:2行ソース版
javascriptが無効になっています。:エラーチェック版
今日が何曜日かプログラムでは出力できませんでした:蛇足版
今日が何曜日かプログラムでは出力できませんでした:おまけ版
今日が何曜日かプログラムでは出力できませんでした:ショートコード
今回の記事は、デザイナーさんやフロントエンドエンジニアさんを対象に、 javascript のあるメソッドの仕様からのプログラムネタ、webで見かけるプログラム紹介記事についての考察、最後におまけとして javascript の教科書本に書いてないと思われるようなネタ(ショートコード化関連)を紹介しています。
メインテーマは「戻り値をわざわざ変数に入れずに配列インデックスにする」というネタなので、web関連なんでもプログラマの人なら知ってるよ~という内容かと思われます。
なので、昔から javascript の教科書本を熟読し、いろんな javascript メソッドをたくさん知っているからこそ、案外知らないかもしれないネタ、なども最後のおまけに書いてみました。
お題は「今日は○曜日です」を表示するプログラムです。
大抵の「 javascript 入門!」とか「初心者のための javascript 」のようなタイトルやキャッチが書いてある javascript の教科書本では、「今日は○曜日です」を表示しましょう、というサンプルを使って for 文や if 文、switch 文などの説明をしている場合があるかと思います。
日付関連の中で、曜日を取得する [getDay()] の値は曜日を表す整数(0~6)が返ってきますので、数値と曜日名を対応させて出力する、という簡単なプログラムになります。
なので、if 文、switch 文などを説明しやすいお題かと思ったりします。
date()関連を紹介している記事では、
var date=new Date();
var day = date.getDay();
などのように、日付オブジェクトを作ってから利用する記述になっています。
[ if ~ else ] を説明するのがテーマになっている教科書通りの場合は、以下のようなソースになるかと思います。
「 if ~ else で書いてみたもの」
このプログラム例では、HTML にある [ id="output" ] が付加されている [ div ] や [ span ] に「今日は○曜日です」という文字列が出力される形となります。
※最後の出力部分については、大抵の教科書や webサイトでは説明したいテーマと異なる内容と考える人が多いためか、console.log() や alert() などになっていることが多いのですが、この記事では実際に webサイトに出力する事例として書いてます。
var date=new Date();
var day=date.getDay();
var str;
if(day==0){str='日';}
else if(day==1){str='月';}
else if(day==2){str='火';}
else if(day==3){str='水';}
else if(day==4){str='木';}
else if(day==5){str='金';}
else if(day==6){str='土';}
document.getElementById('output').innerHTML='今日は'+str+'曜日です';
こういう問題提起用の改善前プログラムサンプルは、修正部分がたくさんあるように作ってみたりする場合もあったりして、上記をわざと、
var date=new Date();
if(date.getDay()==0){…}
else if(date.getDay()==1){…}
…
…のように、if else 判定ごとに毎回 [ getDay() ] させて、何度も同じ値を取得させるようなスマートでない事例を書いておき、変数に代入する件を説明する、などの演出をする場合もあるかもしれません。
また、上記で if(day==0) {str='日';}
等となっている部分を、もっと初心者っぽく、
else if(day==1) {str='月';} …if(day==0) { document . getElementById ( 'output' ) . innerHTML = '今日は日曜日です'; }
else if(day==1) { document . getElementById ( 'output' ) . innerHTML = '今日は月曜日です'; } …
などと大量の文字列表示部分を書いてみたりして、それをもっと短くするネタを追加して記事分量を増量する場合もあるかもしれません。
続けて、if else の条件判定部分 [ day==数値 ] の形が switch 文と同じなので、switch 文の説明したりする流れにしてみたり…。
「 switch 文で書いてみたもの」
var date=new Date();
var day=date.getDay();
var str;
var f=1;
switch(day){
case 0:str='日';break;
case 1:str='月';break;
case 2:str='火';break;
case 3:str='水';break;
case 4:str='木';break;
case 5:str='金';break;
case 6:str='土';break;
default:f=0;break;
}
document.getElementById('output').innerHTML=f?'今日は'+str+'曜日です':'今日が何曜日かわかりません';
問題提起用の改善前プログラムサンプルの中で、例えば、default の部分を用意してみたりすると、後のソースでもそれを実現させていないと、
default はどこいった?と言われてしまう可能性もあったりするので、サンプルソースを作るのは気を使わなければいけないと思ったりします。
※今日は何曜日 プログラムの場合、default は不要かと思ったりもしますが…一応、getDay() の戻り値が 0 ~ 6 以外だった場合(通常ありえないけれど)に「今日が何曜日かわかりません」が表示される形となります。
※細かく記事増量するなら、最後の出力部分を if~else にして、default 時には else の部分が、というような書き方をしておいて、三項演算にするネタを書く、というのも思ったりしましたが、本題ではないので最初から三項演算の記述にしています。
if 文や switch 文、もしかして無理やり for 文?などを使わず、配列データのインデックスとして値を使う
上記のような「今日は○曜日です」を表示するような簡単サンプルプログラムを作る時、超シンプルに配列のインデックスとして getDay() の値を使うのが普通かと思われます。
というか、getDay() の戻り値が 0 ~ 6 になっているのは、言語圏ごとに曜日を表す文言を配列などで指定しやすいように、Monday などではなく、配列インデックスにしやすい 0 からの連番の値を返すのだと思います。
(※ 1 からの連番だった場合、配列インデックスにする時に -1 したり、配列インデックス 0 番に空文字などを指定しなくてはいけなくなって面倒なので、 0 からになっているのだと思います)
また、現在の曜日のみ取得したい形( getDay の値だけ利用)のプログラムですので直接、
d = new Date().getDay();
と記述して、以下のような感じでショートコード化できるかと思います。
「今日は○曜日です」の配列インデックス活用版
//oは出力先タグのid名 ex."output" 等
function op_day_str(o){
var a=['日','月','火','水','木','金','土'];
document.getElementById(o).innerHTML='今日は'+a[new Date().getDay()]+'曜日です';
}
これは、getDay() の結果が 0 ~ 6 の値のどれかになるので、その数値をそのまま配列のインデックス番号に利用している形となってます。(これが今回記事のメインテーマです)
さらに少しだけショートコード化して、以下のように書く場合もあるかもしれません。
function op_day_str(o){
document.getElementById(o).innerHTML =
'今日は'+['日','月','火','水','木','金','土'][new Date().getDay()]+'曜日です';
}
通常はありえませんが、何らかのエラー(ブラウザ側のエラーや getDay への未対応 等)で getDay() が値を返さなかったりすると、配列の値は undefined になり、「今日はundefined曜日です」になるかと思います。
ほぼないとは思いますが、そういう可能性を考えてエラー対策しておきたい場合(上記の switch 文の default 時の対策)は以下のようになるかと思います。
「今日は○曜日です」の配列インデックス活用版(エラー対策)
function op_day_str(o){
var a=['日','月','火','水','木','金','土'],d=a[new Date().getDay()];
document.getElementById(o).innerHTML=d?'今日は'+d+'曜日です':'今日が何曜日かわかりません';
}
※ ローカル変数指定の var はどこに書いててもブラウザが javascript を解析する時に関数の頭で処理してくれますので、[,](カンマ)区切りで一行にしておき、何度も書かないようするとシンプルで使っている配列名・変数名がわかりやすくなるかと思います。
※ d=undefined の場合のみ [偽] となって、三項演算の後ろの方が表示されます。
もちろん、document.get …の部分で id が HTML 内に存在しなかった場合はエラーになり、(引数として渡す id 文字列が間違っていた場合などに発生)
納品前に動いてたのに動かなくなった、となるのは HTML ソースが改変された場合があったりするので特に対策は不要かもしれませんが…(汎用ではなく、そのページ専用プログラムなので)
それでもその点もエラーチェックする場合は以下のようになるかと思います。
この場合、出力先の HTML の初期記述を「今日が何曜日かjavascriptが出力できませんでした」などにしておいてプログラムを補助しておくと便利かと思います。
※定型文言「javascriptを有効にしてください」のような文言を出力先にあらかじめ書いておいて、 javascript が有効なら innerHTML で書き換える、 javascript が無効なら初期メッセージが表示される、という案外忙しいと忘れがちな webサイト制作の定石手法です。
<span id="output3">今日が何曜日かプログラムでは出力できませんでした</span>
プログラムの出力結果は 3 種類になり、
ちゃんと動いた時(これが普通)「今日は○曜日です」(※○にはちゃんと曜日名が入る)、
Date().getDay() の値がブラウザエラー等で取得できなかった場合「今日が何曜日かわかりません」、
HTML が改変されるなどで、[ id : output3 ] が js 側で発見できなかった場合又はユーザが javascript を動作させない設定にしてる場合「今日が何曜日かプログラムでは出力できませんでした」となります。
「今日は○曜日です」配列インデックス活用の蛇足版
function op_day_str(o){
var a=['日','月','火','水','木','金','土'],d=a[new Date().getDay()],e=document.getElementById(o);
if(e)e.innerHTML=d?'今日は'+d+'曜日です':'今日が何曜日かわかりません';
}
配列活用ネタ「戻り値の範囲があらかじめ分かっているので、配列インデックスにすると便利」
今回のテーマは、短く記述するだけが正解ではないけれど、「条件判定文を使わず配列を使って記述を短くする、ある意味配列の普通の使い方」というお話しでした。
余計な条件処理や無理やり for 文を書いてしまうプログラム例は、それらの条件判定文やループ処理などを紹介すること自体がテーマとなっていて、例となっている「今日が何曜日なのか」を表示することがテーマでない場合が多い印象なので、「 getDay() が 0 ~ 6 という数値を返す意味」を考え、そこから配列で短く単純に書くという普通ネタを紹介してみました。
今回のおまけ「実はもっと短くする方法があるんですぅ?!続きはグノ○~で!…じゃなくて…」
「 javascript は配列世界」とどこかの誰かが言ってました(by 遺留捜査)という雰囲気のネタを最後に紹介します。
今回の曜日を指定している部分で a=['日' , '月' , '火' , '水' , '木' , '金' , '土'];
などと記述してますが、この部分を文字列にすることができます。
a='日月火水木金土';
で、プログラム記述は「蛇足版」そのままで動作します。
function op_day_str(o){
var a='日月火水木金土',d=a[new Date().getDay()],e=document.getElementById(o);
if(e)e.innerHTML=d?'今日は'+d+'曜日です':'今日が何曜日かわかりません';
}
「今日は○曜日です」おまけ版
文字列から一文字取得したい時には、[str.charAt(n)] メソッドを使う、などとリファレンス本には書いあったりしますが、 javascript では、配列と同じようにインデックス番号で1文字を抜き出すことができるので…最終的にこうなります。
【HTMLソース】<p><span id="output4">今日が何曜日かプログラムでは出力できませんでした</span>:おまけ版</p>
【javascript】function op_day_str(o){ var d='日月火水木金土'[new Date().getDay()],e=document.getElementById(o); if(e)e.innerHTML=d?'今日は'+d+'曜日です':'今日が何曜日かわかりません'; }
もっと短く?!ってほどではないんですけど、
蛇足版とおまけ版の違いは曜日文字列の指定方法の違いになります。
これはショートコードテクニックの一つで、[charAt] [substr] [substring] 等を使わなくても、文字列から配列記述で 1 文字ずつ文字を取り出すことができる、という方法になります。
今回のおまけその2「var 記述を不要にするショートコード化テクニック」
ついでに以下のショートコードテクニックを使うとvar記述を書かずに済みます。
function op_day_str(o,d,e){
if(e=document.getElementById(o))e.innerHTML=
(d='日月火水木金土'[new Date().getDay()])?'今日は'+d+'曜日です':'今日が何曜日かわかりません';
}
『関数の引数は var 不要のローカル変数』なので、var を書かずにローカル変数としてその文字を使いたい時は、関数を呼ぶ時には渡さなくても良い引数を用意しておく、というテクニックになります。
上記の例では、呼び出す側では第一引数のみ渡し、d や e の値を渡さずに関数を呼びます。
この時の変数 d や e は、その関数で値を入れる前の変数値が undefined になっているだけになります。
つまりは var d,e;
と書くのと同じ、ということです。
また、var でローカル変数指定をする必要がないので、判定部分でやっているような「変数に値を入れる」と「変数値の判定処理」を同時に記述することができるようになります。
if(e=document.getElementById(o))
(d='日月火水木金土'[new Date().getDay()])?
の部分です。
※引数ネタがでたので、ついでに紹介しておきますと、新しい javascript 仕様をすぐに取り入れて実現してくれたクロムさんやファイヤーフォックスさんは、PHP と同様に、関数の引数記述部分でデフォルト値を入れる記述方法
『 function kansu(a,b='',c=0){…} のように引数に直接デフォルト値を指定』
ができたりしますが、IE10 さんが対応してくれてないので、残念ながらまだ活用できないテクニックだったりします。
配列(記述)活用ネタ「文字列からも、配列インデックス番号で文字が取り出せる」
文字列からも配列記述で文字が取り出せる、という小ネタを知らない場合、
他人の javascript ソースを解析していて、どこで配列指定してるんだ?などと悩んでしまったりする場合もあるかもしれません。
javascript の本とかで勉強しているだけだと書いてない、又は書いてあってもそれほど重要視されていない気がしますので、紹介してみました。
知らなかった~アハ体験したYO!などと思ってもらえたら、幸いです。
以上、長い記事を最後まで読まれたみなさん、お疲れさまでした。
ページトップへ