newとコンストラクタ関数で書き直し
@chocolamintさんのフィードバックから、コードを書き直してみた。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>おみくじ</title>
</head>
<body>
<h1>おみくじ</h1>
<input type="button" value="あなたの運勢は?" id="jsButtom">
<p>あなたの運勢は...
<img id="jsResultImage"></img>
<p>文字にすると <span id="jsResultComment"></span></p>
<p>ラッキーアイテムは <span id="jsResultItem"></span></p>
</p>
<script src="js/version7.js" async defer></script>
</body>
</html>
var jsButtom = document.getElementById('jsButtom'); //ボタンをIDでgetしてキャッシュ
var imgFolder = "img/"; //フォルダパスをキャッシュ
var fileExtension = ".png"; //ファイル拡張子をキャッシュ
jsButtom.onclick = function() { //ボタンがonclickされた時に起きる処理
var omikujiList = [
new Omikuji("daikichi", "大吉でした", "大斧!"),
new Omikuji("chukichi", "中吉でした", "中華包丁!"),
new Omikuji("shokichi", "小吉でした", "小麦粉!"),
new Omikuji("suekichi", "末吉でした", "末広がりな8!"),
new Omikuji("kyo", "凶でした。。。", "凶器はダメです")
];
function Omikuji(fileName, comment, item) {
this.fileName = fileName;
this.comment = comment;
this.item = item;
}
var result = Math.floor(Math.random() * omikujiList.length);
var omikuji = omikujiList[result];
document.getElementById('jsResultImage').src = imgFolder + omikuji.fileName + fileExtension;
document.getElementById('jsResultComment').innerHTML = omikuji.comment;
document.getElementById('jsResultItem').innerHTML = omikuji.item;
};
解釈
上から順に、コードの意味を書く。
1. newでオブジェクトを作成
var omikujiList = [
new Omikuji("daikichi", "大吉でした", "大斧!"),
new Omikuji("chukichi", "中吉でした", "中華包丁!"),
new Omikuji("shokichi", "小吉でした", "小麦粉!"),
new Omikuji("suekichi", "末吉でした", "末広がりな8!"),
new Omikuji("kyo", "凶でした。。。", "凶器はダメです")
];
omikujiList
のなかに、new Omikuji
で大吉〜凶の結果を作る。
※ 「オブジェクト」という言葉の使い方はあっているのか?
2. プロパティ名を振る
function Omikuji(fileName, comment, item) {
this.fileName = fileName;
this.comment = comment;
this.item = item;
}
Omikuji
オブジェクトの配列にプロパティ名を振る。
※ 「配列」「プロパティ名」という言葉はあっているのか?
3. 乱数生成
var result = Math.floor(Math.random() * omikujiList.length);
result
変数に乱数生成を代入する。
この時、omikujiList
の中にある配列の長さをlength
で数えて、その中で乱数を生成するようにする。
この辺はドットインストール - JavaScriptで作る「簡単おみくじ」と同じ。
4. 変数に結果を代入する
var omikuji = omikujiList[result];
omikuji
変数にomikujiList[result]
でランダムに選んだOmikuji
プロパティを代入する。
5. 結果を表示させる
document.getElementById('jsResultImage').src = imgFolder + omikuji.fileName + fileExtension;
document.getElementById('jsResultComment').innerHTML = omikuji.comment;
document.getElementById('jsResultItem').innerHTML = omikuji.item;
画像のsrcをimgFolder
とomikuji.fileName
とfileExtension
から参照して表示する。
結果に対応したコメントをomikuji.comment
で参照して表示する。
結果に対応したラッキーアイテムをomikuji.item
で参照して表示する。
ここで大事なのが、omikuji.
以降のプロパティの使い方。
結果表示のプログラムの流れ
結果表示がomikuji.fileName
などでどういう流れで表示されるか考えてみた。
omikuji
の変数を探す。
var omikuji = omikujiList[result]
から、omikuji
はomikujiList
の中からresult
を使ってランダムに選ばれたものが入っていることが分かる。
omikuji
には、今回はnew Omikuji("daikichi", "大吉でした", "大斧!")
が代入されていたとする。
次に、語尾の.fileName
はなにかをnew Omikuji("daikichi", "大吉でした", "大斧!")
の中から探す。
function Omikuji(fileName, comment, item) {
this.fileName = fileName;
this.comment = comment;
this.item = item;
}
で、Omikuji
オブジェクトの中はnew Omikuji("fileName", "comment", "item")
と名前が振られている。
fileName
は、Omikuji
の中の一番左(jsだと0番目)にあるdaikichi
だと分かる。
thisの指すもの
this
が出てきた。
this
はなにを指すのか。
function Omikuji(fileName, comment, item) {
this.fileName = fileName;
this.comment = comment;
this.item = item;
}
this
は自分自身を指すような意味で、この場合Omikuji
を指している。
なので、 大吉 であった場合、Omikuji("daikichi", "大吉でした", "大斧!")
を指している。
書きなおした利点
前回は
var omikujiFileName = ["daikichi", "chukichi", "shokichi", "suekichi", "kyo"];
var omikujiComment = ["大吉でした", "中吉でした", "小吉でした", "末吉でした", "凶でした。。。"];
var omikujiItem = ["大斧!", "中華包丁!", "小麦粉!", "末広がりな8!", "凶器はダメです"];
などと、欲しい結果に対してそれぞれ変数を作って、その中からresult
で結果をランダムに取り出していた。
今回はomikujiList
の中にOmikuji
オブジェクトとしてまとめ、たとえば 大吉 であった場合の、対応する他の結果を分かりやすく書けるようになった。
他の書き方
var omikujiList = [
{ fileName: "daikichi", comment: "大吉でした", item: "大斧!" },
{ fileName: "chukichi", comment: "中吉でした", item: "中華包丁!" },
{ fileName: "shokichi", comment: "小吉でした", item: "小麦粉!" }
// 面倒なのであと2つは省略
];
var omikuji = omikujiList[result];
でも良いが、
また、上のコードだと各おみくじでプロパティ名がきちんと同じかどうかの保証がされないので、コンストラクタ関数を使って以下のようにもできます。
とあるように、ミスを防ぐためにもプロパティ名はいっぺんに振った方が良いことが分かった。
総評
結果の要素を増やしたことで、それぞれの要素の連動と、結果の管理がネックになりそうだと思いついて書き直したことがはじまり。
今回できたコードで、感覚で感じた違和感はクリアになった!
また、よく分かってはいないけど結果内容を他の場所(MySQLとかJSONとか?)にした時にも応用が効く気がしている。
次は
クッキーを使って前の結果をキャッシュとか、カレンダーをつけるとか言ってた。
しかし、本質から脱線して新しいことをやろうとしている気がするので、おとなしくもう少しこのコードを掘り下げよう!