ここでは、初心者から実践的に学べるプログラミングスクール「ウェブカツ!!」のJavaScript・jQuery部入門を受講している生徒の方向けに、さらに理解度を上げるための特訓をしていきます。
出題の回答は全て「JavaScript言語」を使って回答してください。
回答のJavaScript言語は「ES5」で答えてください。
(ES5がよく分からない人は「JavaScript・jQuery部入門どおりの書き方」ってことです。)
開発環境はMacとGoogleChromeブラウザを使います。
Windowsの人もGoogleChromeブラウザを使いましょう。
目次
鬼練1:「仕事と私」どっちを取るのよ!
仕様書
下記要件に従ってプログラムを組んでみてください。
開発ツール(デベロッパーツール)の「console(コンソール)」タブ内に「彼女:仕事と私どっちを取るのよ!」という文字をに表示する
※開発ツール内の文字は見やすいようにデフォルトより文字サイズを大きくしています(開発ツールを開いたら、commandと+記号で文字を拡大できます)
※コンソールの1行ごとの右側に表示されている「index.html?〜〜〜」みたいなのはそれぞれの開発環境によって異なるので無視してください
ヒント
JavaScript(以下、jsと略します)で開発ツールのコンソールに文字を表示させるには
1 |
console.log('なにかしらの文字列をここに入れる'); |
を使います。
答え
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>鬼練1</title> </head> <body> <script> console.log('彼女:仕事と私どっちを取るのよ!'); </script> </body> </html> |
jsの特訓なのでhtmlはなんでもいいです。
ここではbodyタグ内にscriptタグを入れて、その中にjsを直で書いていっています。
入門編の部活の練習でやりましたね?いくつかのjsの書く場所があったの覚えてますか?
- headタグ内にscriptタグで囲って書く
- bodyタグ内にscriptタグで囲って書く
- headかbodyタグ内にscriptタグで別で書いて作ったjsファイルを読み込む
でしたね。
その中の2つ目の書き方ですね。
実際こんな書き方したら、現場では「低レベル」「初心者丸出し」判定くらうので注意しましょう。
見やすさ・保守性のためにも「jsは別ファイルで書いて読み込む」のが定石です。(とは言っても、古いシステムをずっと運用している現場に行くといまだにhtmlファイル内にjsが直接ベタ書きされていますが)
今後の鬼練の答えは全てこのscriptタグ内だけを記載していきます。
さて、今回の答えは簡単ですね。
1 |
console.log('彼女:仕事と私どっちを取るのよ!'); |
でコンソールに表示させるだけです。
文字列は「’(シングルクウォート)」か「”(ダブルクウォート)」で囲えば、機械(ブラウザ)には「文字」として判別してくれます。
試しに外したらどうなるか?言われなくとも、やってみましょうね。
シングルかダブルかどっち使った方がいいの?というと「シングルクウォート」を基本は使ってください。
なぜか?はゆくゆく部活を進めていけば、わかっていきますので。
(そこらへんの解説もしています)
鬼練2:「仕事と私」どっちを取るのよ!修羅場編
前回の続きです。
彼女の気持ちに正直に答えたら、修羅場になっちゃったパターンです。
仕様書
下記要件に従ってプログラムを組んでみてください。
開発ツール(デベロッパーツール)の「console(コンソール)」タブ内に
「彼女:仕事と私どっちを取るのよ!」という文字をに表示させる
その次に
「自分:◯◯◯」を表示させる。
◯◯◯は変数(変数answerとする)にしておき、その変数の中身を表示させる。
変数answerには「仕事に決まってるだろ!」の文字列を入れておく。
変数answerの中身が「仕事に決まってるだろ!」だった場合には、
「彼女:あたたたたたたたっーーー!!」と
「自分:ひでぶっ!!」という文字を表示させる
答え
1 2 3 4 5 6 7 8 9 |
var answer = '仕事に決まってるだろ!'; console.log('彼女:仕事と私どっちを取るのよ!'); console.log('自分:' + answer); if(answer === '仕事に決まってるだろ!'){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } |
jsで書くとこんな感じですね。
STEP1:変数answerの定義
まず変数answerという箱を用意して、その中に「仕事に決まってるだろ!」という文字列を入れておきますね。
「変数」というのはやりましたね?プログラミング言語の最初の関門です。
変数は「箱」です。ただの箱。ダンボールの箱的なやつです。
箱の中には色々なデータを入れておけるわけですね。
データには「文字列」やら「数値」やら「種類(型)」ってもんがありましたね?
型については、今の段階では「なんとなく」でいいです。
「数値」と「数字(文字列)」が違うのだけ分かっとけばね。
(あとBoolean型という「true」と「false」という値があることも)
ここらへんは「書いて慣れる」しかありません。
STEP2:文字列の連結でコンソールに表示
話もどって、変数用意したら、そのあとに2つのconsole.logで文字を表示します。
1 |
console.log('自分:' + answer); |
で変数の中身もコンソールに表示してますね。
「+(プラス記号)」を使うことで、文字列を「連結」させることができます。
今回は「自分:」という文字列と「変数(中には文字列が入っている)」を連結させているわけですね。
そして、連結されて「1つの文字列」としてコンソール(画面)に表示されたわけです。
今回、コードが見やすいように+記号の前後には「半角スペース」を入れていますが、なくても動きます。
試してみましょう。
逆に半角スペースいっぱい入れてみたらどうなんの?とかもやってみましょうね。
動けばそれでも動くってことだし、動かなきゃ動かないんですよ。
当たり前だけどその感覚を身に着けることです。
新しい電化製品買った時も、まず説明書見て使い方覚えるよりも動かしながら「ここは、こうなのか」ってやった方が覚えるでしょ?
なので、動かしまくることです。PCは壊れやしないんで。
また、2行目と5行目を改行してますが、これも「見やすいように」というだけで、改行しなくたって動きます。
でも、改行した方がなんだか見やすいですよね?
STEP3:変数answerの中身をif文で判定する
出ました、プログラミング言語の次の関門「if」ってやつ。
日本語で言うと「もし、〜〜ならこの処理をする」っていう書き方が出来るものです。
それが、これですね。
1 2 3 4 |
if(answer === '仕事に決まってるだろ!'){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } |
if文の書き方はやりましたね?
1 2 3 |
if(判定したい式をここに書く){ // 「もし、◯◯なら」の場合に当てはまった時に実行したい何らかの処理をいろいろ書ける } |
という書き方です。
判定式は
「===」という「左と右の値が同じだったら」という肯定系や
「!==」という「左と右の値が違ったら」という否定形
なんかがありましたね。
他のプログラミング言語では「==」と「!=」が一般的ですが、jsや今後やるPHPに限っては使わないようにしましょう。
「===」や「!==」といった「厳密比較」と呼ばれる比較式を使うようにしましょう。
厳密比較では値の「型」も同じかどうか?まで判定されるものです。
今の時点でよく分からなければそのうちわかっていきます。
今回の場合だとif文のカッコの中は
1 |
answer === '仕事に決まってるだろ!' |
ですね。
なので
変数answer(の中身)と文字列「仕事に決まってるだろ!」が同じ場合
という意味の式になりますね。
厳密比較なのでお互いの「型」まで同じかどうか?を判定します。
左辺の変数answerの中には
文字列型の「仕事に決まってるだろ!」
という値が入っていて、右辺も
文字列型の「仕事に決まってるだろ!」
という値なので、
「型も値も同じ」
ってことになりますね。
判定の結果というのは「true」または「false」のboolean型で返ってきます。
なので、
1 2 3 4 |
if(answer === '仕事に決まってるだろ!'){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } |
というif文の中身の判定がまず最初にされて、trueという結果になり
1 2 3 4 |
if(true){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } |
に変わります。(内部的に変わってるだけで目に見えるわけじゃないですよ?)
そして、if文というのは
判定式内が「true」の時に「{(波括弧)」内の処理を行う
という決まりがあるので、今回の場合は中身の処理が実行されてコンソールに表示されるわけですね。
鬼練3:「仕事と私」どっちを取るのよ!結局修羅場編
前回の続きです。
彼女の気持ちに正直に答えたのに、結局また修羅場です。
仕様書
下記要件に従ってプログラムを組んでみてください。
開発ツール(デベロッパーツール)の「console(コンソール)」タブ内に
「彼女:仕事と私どっちを取るのよ!」という文字をに表示させる
その次に
「自分:◯◯◯」を表示させる。
◯◯◯は変数(変数answerとする)にしておき、その変数の中身を表示させる。
変数answerには「仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。」の文字列を入れておく。
変数answerの中身が「仕事に決まってるだろ!」だった場合には、
「彼女:あたたたたたたたっーーー!!」と
「自分:ひでぶっ!!」という文字を表示させる
変数answerの中身が「仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。」だった場合には、
「彼女:仕事してこいやーーーーーー!!」と
「自分:ひでぶっ!!」という文字を表示させる
もう、あれですね、この彼氏、あれです。
きっとダメ男です。それか超ブラック会社か。
答え
1 2 3 4 5 6 7 8 9 10 11 12 |
var answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; console.log('彼女:仕事と私どっちを取るのよ!'); console.log('自分:' + answer); if(answer === '仕事に決まってるだろ!'){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } else if (answer === '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。') { console.log('彼女:仕事してこいやーーーーーー!!'); console.log('自分:ひでぶっ!!'); } |
まずは、変数answerに文字列入れてますね。
前回と違うのは9行目からです。
if文の{}の終わりにくっついてるこいつです。
1 2 3 4 |
else if (answer === '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。') { console.log('彼女:仕事してこいやーーーーーー!!'); console.log('自分:ひでぶっ!!'); } |
これは「else if(エルスイフ)」といいます。
「else-if文」ってやつです。
1 2 3 4 5 |
if(判定式){ //処理いろいろ1 } else if (判定式) { //処理いろいろ2 } |
if文のあとにつけられるもので、
「else if」と書いてif文と同じくカッコ内に判定式を書けます。
「elseif」じゃダメです。「else」と「if」には半角スペース必ず必要です。
そのカッコ内の判定がtrueだった場合に{}内の処理を行えます。
なので、日本語でいうところの
「もし◯◯だった時にこの処理をして、
もし◯◯だった時にはこっちの処理をする」
というように条件を複数に分けられるってことです。
else-if文は1つだけじゃなく、こんな感じにいくつも「もし◯◯だったら」を加えられます。
1 2 3 4 5 6 7 8 9 |
if(判定式){ //処理いろいろ1 } else if (判定式) { //処理いろいろ2 } else if (判定式) { //処理いろいろ3 } else if (判定式) { //処理いろいろ4 } |
else-if文の注意点としては「どっちかの条件の処理しかしない」ということです。
最初のifの判定式でtrueだったなら、次のelse ifの判定式は行いません。
なので、もし全部の「もし〜」に当てはまらなければ、中の処理はどれも行われないってことになりますね。
鬼練4:「仕事と私」どっちを取るのよ!運命の選択編
前回の続きです。
彼女の気持ちに正直に答えたいです。ランダムで。
仕様書
下記要件に従ってプログラムを組んでみてください。
開発ツール(デベロッパーツール)の「console(コンソール)」タブ内に
「彼女:仕事と私どっちを取るのよ!」という文字をに表示させる
その次に
「自分:◯◯◯」を表示させる。
◯◯◯は変数(変数answerとする)にしておき、その変数の中身を表示させる。
変数answerには
「仕事に決まってるだろ!」
「仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。」
のどちらかの文字列をランダムで入れておく。
変数answerの中身が「仕事に決まってるだろ!」だった場合には、
「彼女:あたたたたたたたっーーー!!」と
「自分:ひでぶっ!!」という文字を表示させる
変数answerの中身が「仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。」だった場合には、
「彼女:仕事してこいやーーーーーー!!」と
「自分:ひでぶっ!!」という文字を表示させる
ヒント
ランダムを実現するには
1 |
Math.floor(Math.random()*2); |
と書くことで、0または1どちらかの数値が結果として返ってきます。
(どういう仕組みかは今の時点では気にしなくていいです。こう書けば0か1の値がもらえるんだなとだけ思っておいてください)
なので、その結果を変数に入れるなら
1 |
var rand = Math.floor(Math.random()*2); |
といったような感じで書けますね。
この例では、変数randの中に0か1のどちらかの値がランダムで格納されます。
答え
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
var answer = null; var rand = Math.floor(Math.random()*2); if(rand){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else{ answer = '仕事に決まってるだろ!'; } console.log('彼女:仕事と私どっちを取るのよ!'); console.log('自分:' + answer); if(answer === '仕事に決まってるだろ!'){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } else if (answer === '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。') { console.log('彼女:仕事してこいやーーーーーー!!'); console.log('自分:ひでぶっ!!'); } |
前回と違うのは、1行目〜8行目までです。あとは全部前回といっしょ。
STEP1:変数の定義と初期化
まず、今回の一連の処理で使っていく変数をまず定義しておきましょう。
1 |
var answer = null; |
では、変数answerを「定義」しました。
しかし、あとあとでその変数には値を入れるので今は「空」にしておきたいので
「値は空ですよ〜」という意味の値の
「null(ヌル)」
というものを入れておきます。
「値は空という意味の値」
ってめっちゃ意味わからないですけどね。。
「そういうもん」って思うしかありません。そういう「決まり」なんです。
nullはプログラミング言語特有の値ですね。
ちなみに実は
1 |
var answer; |
とも書けるし
1 |
var answer = ''; |
と書く人もいます。
ここらへんはエンジニアによりけりです。
微妙に意味は違っていて、
1 |
var answer; |
は変数answerは「定義」したけど「初期化」はしてない。
という状態です。
定義と初期化の違い
定義というのは、
「この変数使うから箱作ったよ!」
ということです。
なので、この状態では中身には何も入っていません。
(空を表すnullという値も入っていない)
初期化というのは、
定義と同時に値を最初に入れておく
ことをいいます。
なので、nullを最初に入れてたのも「初期化」してるし
1 |
var answer = ''; |
も定義して、初期化してます。この例だと
「”(空文字)」とよばれる「空の文字」を入れている。
ということになります。
空の文字ってなんだよ。。。。。。
ってな感じですが、「そういうもん」として覚えるしかありません。慣れ。です。
空文字とは「文字列型の値で中身が空」というものです。
型としては「文字列型」なんですね。
ちなみに「null」は「null型」という型になります。
js特有のundefined型
ちなみにさっきのこれ
1 |
var answer; |
実は初期化してませんが、中身はきちんと入っています。
何が入っているかは
console.log
で表示させてみれば分かります。
「undefined」
と出てきますね?
これはjs特有のもので、
「undefined」という型の「undefined」という値
です。
わけわからんですね。
何度も言いますが、そういうもんだと思うしかありません。慣れ。です。
他のプログラミング言語とは違い、jsでは
変数を定義しただけで初期化しない場合にはundefined値が中に入る
という決まりがあります。
で?
という感じですが、そこらへんはゆくゆくわかっていくので今は
「へー」
と思っていてください。
じゃあ、さっきの3つの書き方で違いがあるの?
というと
ほぼありません。
あるにはありますが、今のみなさんの段階では分からないのと書いていて不具合が起こるとか何か影響があることもありません。
なので、なんでもオッケーです。
STEP2:ランダムな値を変数に入れる
長くなりましたが、次にランダム値を変数に一旦入れておきます。
1 |
var rand = Math.floor(Math.random()*2); |
ですね。
STEP3:ランダムな値を判定して文字列を返事を入れる
あとは3行目からのやつです。
1 2 3 4 5 |
if(rand){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else{ answer = '仕事に決まってるだろ!'; } |
変数randには数値型で0か1が入っています。
それをif文で判定し、どっちでもいいんですがifまたはelseの処理で文字列を入れてやります。
分からないところがいくつか出てきましたね??
1つ1つ解説します。
if文の判定結果は自動で変換(キャスト)される
if文の判定ってboolean型のtrueまたはfalseの値だったらで処理がされるんだよね?
変数randには数値の0か1が入ってるんでしょ??
なんで判定できるの??
ってか、そもそも式にすらなってなくね??
そんな考えがよぎりますね。
実は、
if文の判定は「式」でなくともいいんです。
なので
1 2 3 |
if(true){ } |
でもいいし
1 2 3 |
if(1){ } |
でもいいし
1 2 3 |
if('あいうえお'){ } |
でもいいんです。
どういうことかというと
jsでは
値を自動で使いたい型に変換する
という仕組みがあるからです。
型を変換することを
キャスト
といいます。
どのプログラミング言語にも「型」があるので、「キャスト」という仕組みが必ずあるんですが
「自動で勝手にプログラミング言語がキャストしちゃう」のは有名どころではjsとphpくらいなものです。
たとえば、if文のカッコ内であればtrueまたはfalseで判定をしたいんです。
なので、
勝手にtrueまたはfalseの値に勝手に変換する
わけです。jsくんが。(jsさんかもしれない)
1 2 3 |
if(1){ } |
だったら、
「数値の1はtrueだ!」
と
1 2 3 |
if(true){ } |
に変換しちゃいます。(内部的になので目には見えませんよ?)
また、
1 2 3 |
if('あいうえお'){ } |
だったら
「文字列はtrueだね!」
とこれまた
1 2 3 |
if(true){ } |
とboolean型のtrueという値に変換しちゃいます。
boolean型に変換さえしちゃえば、if文は判定できますからね。
ここらへんは、
らへんをみてください。
nullや数値の0や空文字、undefinedという値は「false」
ですね。
文字列の「0」や「あいう」などや数値の1は「true」
になります。
if-else文
なので
1 2 3 4 5 |
if(rand){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else{ answer = '仕事に決まってるだろ!'; } |
というif文の中に変数いきなりぶっこんでも判定してくれるわけですね。
変数randの中には数値型の1か0しか入らないので
1ならtrue
と判定されるし
0ならfalse
と判定されますからね。
そして、他にも初見のものが「else」です。
前回「else if」というのはやりましたね。
同じ感じで「else」というのは「それ以外全て」と言う意味です。
なので、この例だと
変数randがtrueだった場合はこっちの処理をして、
それ以外だった場合はこっちの処理をする
という意味の書き方になります。
elseは「条件に当てはまらない場合に必ず何かしらの処理をしたい」という時に使います。
今回は変数randがtrueだった場合(数値の1だった場合)に片方の選択をし、
そうでなかった場合にもう片方の選択をさせる。
という形で十分なのでelseを使いました。
もちろん
1 2 3 4 5 |
if(rand === 1){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else{ answer = '仕事に決まってるだろ!'; } |
でも正解で
1 2 3 4 5 |
if(rand === 1){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else if(rand === 0){ answer = '仕事に決まってるだろ!'; } |
でも一応正解です。変数randには数値の1か0かしか入ってこないわけですからね。
コードは出来るだけ短く書こう
ただ、短く書けるに越したことはありません。
ただし、短くしすぎて他の人が見辛いコードになったのでは意味がありませんので注意してください。
1 2 3 4 5 |
if(rand === 1){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else if(rand === 0){ answer = '仕事に決まってるだろ!'; } |
の書き方もif文は勝手にキャストしてくれて判定してくれるわけですから、
1 2 3 4 5 |
if(rand){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else if(!rand){ answer = '仕事に決まってるだろ!'; } |
と書けばいいわけです。
「elseif」の判定式の変数の前についている「!(ビックリマーク)」は
「否定(trueでない場合=falseの場合)」
を表すものです。この場合だと
「変数randがtrueでない場合(falseの場合)にこの処理を実行する」
という意味になります。
なので、変数randには1か0かなので、
変数randの中身が0だったのなら、
「変数randはfalse(0は自動でキャストされてfalseと判定される)」
ということになり、その中の処理が実行されます。
また、結局「falseの場合」ということなんであれば最初の答えの通り
1 2 3 4 5 |
if(rand){ answer = '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。'; }else{ answer = '仕事に決まってるだろ!'; } |
としてelse(それ以外)としまっていいわけですね。
こっちの方が今回の例題だとスマートです。
さらにもっとスマートに書く方法があります。
ショートハンドで書こう
「ショートハンド」と呼ばれる「省略記法」を使った書き方です。
1 |
answer = (rand) ? '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。' : '仕事に決まってるだろ!'; |
こうするとif-else文が1行で書けちゃいます。
書き方のルールは
1 |
(判定式) ? 何かしらの値A : 何かしらの値B; |
となります。
「カッコ」と「?(クエスチョンマーク)」と「:(コロン)」が大事です。
カッコ内の判定式がtrueの場合に「何かしらの値A」が返され、falseなら「何かしらの値B」が返されます。
この例だとその値を変数answerに入れている。ってことです。
処理内容は普通にif-elseで書くのと全く同じ動きになりますね。
出来るだけ短く(分かりやすさはそのままに)書けた方がいいので、今回の場合だと実はこっちの方を使った方がいいです。
これで、ブラウザを何度かリロード(更新)するたびに自分の選択肢がランダムに変わっていきますね。
「if」と「else if」と「else」の組み合わせ方
ちなみに「if」と「else if」と「else」を組み合わせる場合は
1 2 3 4 5 6 7 |
if(rand === 1){ }else if(rand === 0){ }else{ } |
というように
ifではじまり、
else-ifを書き(複数OK)
最後にelse
という順番の決まりがあるので注意しましょう。
リファクタしてみよう!
さきほどのように最初のコードから大分短くなりましたね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var answer; var rand = Math.floor(Math.random()*2); answer = (rand) ? '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。' : '仕事に決まってるだろ!'; console.log('彼女:仕事と私どっちを取るのよ!'); console.log('自分:' + answer); if(answer === '仕事に決まってるだろ!'){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } else if (answer === '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。') { console.log('彼女:仕事してこいやーーーーーー!!'); console.log('自分:ひでぶっ!!'); } |
こういったようにプログラミングのコードをさらに
「分かりやすいもの」「短く簡潔なもの」「あとあと修正しやすいもの」
に変えていくことを「リファクタ(リファクタリング)」といいます。
実際に上記のコードはもっとリファクタリングできます。
まず、こうリファクタできます。
1 2 3 4 5 6 7 8 9 10 11 12 |
var answer = (Math.floor(Math.random()*2)) ? '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。' : '仕事に決まってるだろ!'; console.log('彼女:仕事と私どっちを取るのよ!'); console.log('自分:' + answer); if(answer === '仕事に決まってるだろ!'){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } else if (answer === '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。') { console.log('彼女:仕事してこいやーーーーーー!!'); console.log('自分:ひでぶっ!!'); } |
変数answerを定義時に初期化してしまい、初期化の時にランダム判定しちゃう。
って方法です。
だって、変数randは変数answerの中に値を入れる時の1度きりしか使いませんよね?
ちょっと今の段階では分かりにくい話になっちゃいますが、
「変数を作るとPCのメモリを消費する」
というデメリットがあります。
この例程度のコードであれば影響は全然ないですが、膨大なコードになった場合や特にPCほどスペックがないスマホでサイトを閲覧した際に違ってきます。
メモリを食う(消費する)ということは、その分動作処理に時間がかかりますし、いわゆる「サイトが重くなる」という現象が起こっていきます。
なので、箱を用意しなくていいのであれば用意しないことに越したことはありません。
逆に変数に名前をつければ、その値がどんな意味・役割で使われるものなのか?が分かりやすくなるというメリットもあるので、変数を用意するかどうかは時と場合によります。
また、さらにこんな風にリファクタ出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var CHOICES = ['仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。', '仕事に決まってるだろ!']; var answer = (Math.floor(Math.random()*2)) ? CHOICES[0] : CHOICES[1]; console.log('彼女:仕事と私どっちを取るのよ!'); console.log('自分:' + answer); if(answer === CHOICES[0]){ console.log('彼女:あたたたたたたたっーーー!!'); console.log('自分:ひでぶっ!!'); } else if (answer === CHOICES[1]) { console.log('彼女:仕事してこいやーーーーーー!!'); console.log('自分:ひでぶっ!!'); } |
「選択肢」という意味の変数CHOICESを作り、変数answerに入れる際や7・10行目の分岐の判定式で使うようにします。
変数CHOICESには「配列」というものを使っていますね。
部活でやりましたね?
変数の中に「間仕切り」をして、複数の値を入れておけるものです。
変数(ダンボール箱)の中に仕切り区切ってあるような状態です。
配列の書き方はこうですね。
1 |
var arr = ['文字列だったり', 25, true]; |
普通に変数を作ってあげて、[](カギカッコ)を使う事で、その中に入れる値には文字列なり数値なりboolean値なり、色々な値を入れる事ができます。
カギカッコの中で「,(カンマ)」で区切ることで、「仕切りを増やしている」ってことです。
配列の中の値にはそれぞれ「番号(添字とかインデックスといいます。)」がついていて、番号は必ず0から始まります。
配列の中身の値を取り出したい時には配列名の後にカギカッコでインデックス番号を指定すれば取り出せます。
なので、
1 2 3 4 |
var arr = ['文字列だったり', 25, true]; arr[0]; // 文字列だったり arr[1]; // 25 arr[2]; // true |
という使い方とになるわけですね。
配列に値を入れるには
1 2 3 |
var arr = ['文字列だったり', 25, true]; arr[1] = true; arr[1]; // true |
というようにインデックスで指定した配列内に普通に値を入れれば上書きされます。
新たに配列の後ろに値を追加したい時は
1 2 3 |
var arr = ['文字列だったり', 25, true]; arr[] = '新たに追加した文字列です'; arr[3]; // 新たに追加した文字列です |
と空のカギカッコにして中に値を入れてやります。
他にも配列の使い方はここらへんに載ってます。
https://qiita.com/takeharu/items/d75f96f81ff83680013f
こういうように配列のCHOICESを作れば、同じ文字列を何度も書かなくてよくなりますよね?
しかも、選択肢を変えたければ、変数CHOICESの中身を変えるだけで済みます。
らくちん♪
もし、それぞれ変数answerに入れる際やif文の判定式で「ベタ書き」をした場合、
それぞれの箇所を修正する必要が出てきちゃいます。
実際の現場では「極力修正箇所を少なくする」のはとても大事です。
なぜなら、「修正する」ということは
「バグを生む可能性がある」
ということだからです。
人間が書くわけですからね。ちゃんと修正出来ているか保証できません。
なのでどうするか?
「その部分をテストをする」
わけです。
テストの工数(時間)がかかり、時間がかかればお金が発生します。
なので、極力あとあとの修正箇所が少なくて済む書き方をする必要があるわけですね。
こういったコードの書き方を
保守性の高いコード
と言ったりします。あとあと修正しやすいコード。ってことですね。
何度も言ってますが、この例程度のコード量ならほとんど意味ないですが、実際の現場の大量のコードがある中ではここらへの「書き方」が効いてきます。
ちなみに変数CHOICESをなぜ「大文字」にしてるか?というと
「定数」
という意味合いですよ。と普通の変数と違うんだと分かりやすくするためです。慣例ですね。
jsのES5では定数というものが存在しないので。
(ES6からは「const」というもので定数を作れますが)
定数とは「あとあとで中身を変更することがない箱」ということです。
選択肢の中身は変わりませんよね?なので、
この箱の中身はあとあと変わることはないよ。と他の人がコードを見た時に分かりやすいように定数として定義するわけです。
さらにこんな書き方が出来るともっとスマートです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var CHOICES = { YOUR: '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。', WORK: '仕事に決まってるだろ!' }; var answer = (Math.floor(Math.random()*2)) ? CHOICES.YOUR : CHOICES.WORK; console.log('彼女:仕事と私どっちを取るのよ!'); console.log('自分:' + answer); if(answer === CHOICES.WORK){ console.log('彼女:あたたたたたたたっーーー!!'); } else if (answer === CHOICES.YOUR) { console.log('彼女:仕事してこいやーーーーーー!!'); } console.log('自分:ひでぶっ!!'); |
定数CHOICESを「連想配列」にしちゃう書き方です。
連想配列もやりましたね?
配列に「名前」をつけられるものですね。配列は複数の値に番号がついてるだけでしたが、それぞれに名前をつけることができるのが連想配列です。
連想配列は配列と違って{}(波括弧)で囲った中にカンマで区切って値を入れます。
1 2 3 4 |
var CHOICES = { YOUR: '仕事よりも君が大事さ。仕事はもう嫌で嫌で嫌で。。嫌で嫌で嫌で。。ほんと嫌なんだ。', WORK: '仕事に決まってるだろ!' }; |
値には名前がつけられるので、
1 |
名前: 値 |
というように「:(コロン)」で区切ってやります。
名前は英数字で小文字でも大文字でもいけます。(今回は定数なので大文字で名前をつけてますが、通常は小文字でつけるのが慣習です)
連想配列の使い方は、こちらなんかを見てください。
話戻って、配列でもいいんですが、使う箇所で
1 |
CHOICES[0] |
とかってやってしまうと
このコードを何も知らない人が見た時に
「中身は何入ってんだ?これ?」
と分かりにくいですね。
なので、配列の中の値に「名前」をつけられる「連想配列」を使うことで
1 |
CHOICES.YOUR |
といったように各箇所で呼び出すことで
誰かがコードだけをパッと見た時にも
「どんなデータを呼び出しているか?どんなデータがこの中に入っているのか?」
が分かりやすくなります。
出来るだけ使うデータは「ベタ書き」せずに変数なり定数に入れて使う。
ということを覚えておきましょう。
さらには
1 |
console.log('自分:ひでぶっ!!'); |
はどっちの選択肢でも結局表示させるわけなので
if文が終わったところに書いてあれげれば1行で済みますね。