0
Help us understand the problem. What are the problem?

posted at

updated at

Webの勉強はじめてみた その8 ~JavaScript編 オブジェクト~

N予備校の「プログラミング入門 Webアプリ」を受講しています。
今回は第一章12節「JavaScriptのオブジェクト」です。

学んだこと

1. オブジェクト内のプロパティは「,」で区切る。 2. 配列みたいに参照できる 3. プロパティの値は省略できる。

配列みたいに参照できる

var student = {
    name = 'Jake',
    age = 16
}
student['name'];

プロパティの値は省略できる

var age = 13;
var student = {
    name = 'Jake',
    age
}

気を付けたいこと

1. メソッドの実行は必ず()をつける 2. 未実装の箇所はコメントで //TODO をつけること

メソッドは()つけるとすぐに実行されるイメージでいいのかな?
下の練習問題ではstop()をつけないでonkeydownプロパティに代入してるので、そういう認識でいます。

練習問題:時間あてゲーム

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>
        JavaScript のオブジェクト            
    </title>
</head>
<body>
    <h1 id="display-area"></h1>
    <div id="time-area"></div>
    <script src="object.js"></script>
</body>
</html>
var game ={
    startTime: null,
    displayArea: document.getElementById('display-area'),
    timeArea: document.getElementById('time-area'),
    start: function (){
        //現在時刻を開始時刻として記憶
        startTime = Date.now();
        //キー押下でストップ処理
        document.body.onkeydown = game.stop;  
        //リアルタイム表示
        setInterval(game.displayTime, 50);        
    },
    stop: function (){
        //ストップ時刻を記憶
        var currentTime = Date.now();
        //経過時間取得
        var seconds = (currentTime - startTime) / 1000;
        //結果表示
        var rslt = seconds + "秒でした。";

        if(9.5 <= seconds && seconds <= 10.5){
            game.displayArea.innerText = rslt + "すごい!";
        }else{
            game.displayArea.innerText = rslt + "残念!";
        } 

    },
    displayTime: function(){
        //経過時間の表示
        //game.timeArea.innerText = (Date.now() - game.startTime) / 1000;
        game.timeArea.innerText = (Date.now() - startTime) / 1000;
    }
}

//ページ読み込み時に使う処理
var isConfirm = confirm('OKを押して10秒だと思ったら何かキーを押してください');
if(isConfirm){
    //タイマースタート
    game.start();    
}

不明なところ

同じオブジェクト内のメソッドからプロパティを呼び出す時、オブジェクト名を頭につけると予期しない挙動になった

displayTime: function(){
        //経過時間の表示
        console.log(startTime);
        console.log(this.startTime);
        console.log(game.startTime); // nullになる
        //この参照だとnullになってDate.now()の値だけが表示される。
        //game.timeArea.innerText = (Date.now() - game.startTime) / 1000;
        //startTime か this.startTime であれば問題ない 
        game.timeArea.innerText = (Date.now() - startTime) / 1000;
    }

どれもnullになるなら、まだスコープの問題だとかで理解はできそうなんだけれど。
ここがどうもしっくりきてないです。

まとめ

不明なところもあるので、ちょっとすっきりしてないですが。
今回で一旦JavaScript編は終了みたいです。
次回はCSS編に突入します。

追記(2021/12/05)

game.startTimenullになる件で、原因が判明したので追記します。

    startTime: null,
    displayArea: document.getElementById('display-area'),
    timeArea: document.getElementById('time-area'),

    start: function (){
        //現在時刻を開始時刻として記憶
        //startTime = Date.now();
        game.startTime = Date.now();
        //キー押下でストップ処理
        document.body.onkeydown = game.stop;  
        //リアルタイム表示
        setInterval(game.displayTime, 50);        
    },

結論から言えば、
startメソッド内のstartTimeがグローバル変数として扱われて(varと同じ扱い)、オブジェクトのstartTimeとは別物になっていたことが原因。

varの扱いの厄介さを少し垣間見た気がします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?