質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

332閲覧

javascriptで作ったタイマーが動作しません

tanakashouzoux

総合スコア52

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/05/12 10:12

変数dをコンソールに表示してカウントアップする様にしたいのですが、NANと出てしまいます

変数dを使わなければ上手く行くのですが、どうして変数dを使うと上手くいかないのかが分かりません

詳しい方教えて頂けないでしょうか?

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Stopwatch</title> 7 <link rel="stylesheet" href="css/style.css"> 8</head> 9<body> 10 11<div id="timer">00:00,000</div> 12<button id="start">start</button> 13<button id="stop">stop</button> 14<button id="reset">reset</button> 15 16 17 18<script src="js/main.js"></script> 19</body> 20</html>

javascript

1'use strict'; 2{ 3 const timer=document.getElementById('timer'); 4 const start=document.getElementById('start'); 5 const stop=document.getElementById('stop'); 6 const reset=document.getElementById('reset'); 7} 8 9 10let startTime; 11 12let elapsedTime; 13 14let d=elapsedTime-startTime; 15 16start.addEventListener('click' , ()=>{ 17 18 startTime=Date.now(); 19 20 countUp(); 21 22 }) 23 24 function countUp(){ 25 26 elapsedTime=Date.now(); 27 28 console.log(d); 29 30 setTimeout(countUp , 10); 31 32 } 33

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

初期値が設定されてない変数同士で計算しても結果はNaNですよ。

js

1 2let startTime; 3 4let elapsedTime; 5 6let d=elapsedTime-startTime; 7 8console.log(d);

きちんと値が入ったタイミングで計算してください。

ミニマムコードで解説。

もっと簡単なコードで紐解きましょう。

下記のコード、出力結果は「undefined」です。

js

1let a; 2let b; 3 4b = a; 5test(); 6function test(){ 7 a = "test"; 8 console.log(b); 9}

でも質問者さんは「なぜtestが出ないの?」と言っています・

では処理はどの順番で通っているか確認しましょう。

js

1console.log(1); 2let a; 3console.log(2); 4let b; 5console.log(3); 6b = a; 7console.log(4); 8test(); 9console.log(5); 10function test(){ 11 console.log(6); 12 a = 2; 13 console.log(7); 14 console.log(b); 15 console.log(8); 16} 17console.log(9);

出力結果

1 2 3 4 6 7 undefined 8 5 9

質問者さんの理論を成り立たせるためには、7の次に1~4をもう1度通っている必要があります。
でも、通ってませんね?
bに値が代入されたのはグローバルで実行された3と4の間のみです。

提示のコードでは、startTimeやelapsedTimeは宣言後に、明確に値が代入されるように書かれています。
しかも、setTimeoutを実行しているため、countUp()が何度も実行され、elapsedTimeは更新され続けていることになります。
私のサンプルコードと同じようにあらゆる箇所にconsole.log()で出力させてみてください。
クリック前に、変数定義部分を通り、クリックしたらstartTime=Date.now();が一度だけ実行された後は下記が延々と繰り返されているはずです。
elapsedTime=Date.now();の代入console.log(d);でNaN出力setTimeout(countUp , 10);

投稿2020/05/12 10:24

編集2020/05/12 11:54
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanakashouzoux

2020/05/12 10:30

わざわざご回答ありがとうございますm(__)m 失礼なのですが、値が入ったタイミングとはどういうことなのでしょうか??
m.ts10806

2020/05/12 10:31

ご自身で書かれてますよ。計算対象の変数に値が入る処理を。
tanakashouzoux

2020/05/12 10:37

何度もありがとうございます! 変数に値が入るタイミングが良く分かっていませんでした???? ありがとうございます!
m.ts10806

2020/05/12 10:48

どのような順番で処理が流れているか、あらゆるところにconsole.log()を書いて出力してみると良いです。
tanakashouzoux

2020/05/12 10:59

ありがとうございます! console.log()色んなところに書いてみたいと思います! startTime、elapsedTimeは let startTime; let elapsedTime; と最初に宣言していても Date.now() が代入されるのに d=elapsedTime-startTime には代入されないのがとても違和感があるのですが、これは仕様?なのでしょうか?
m.ts10806

2020/05/12 11:01

勝手に代入されるわけではないです。 「代入する処理」を書いているから代入されるのです。 dに代入する処理が書かれているのはelapsedTimeとstartTimeが宣言された時点です。書いた通りに動いています。
m.ts10806

2020/05/12 11:03

JavaScriptは「イベント駆動」です。 「こういうイベントが起きた時」に動作するように書きます。 「こういうイベント」が明示されてなければ、その処理が読み込まれた時に実行されます。 なので、dに代入する処理はelapsedTimeとstartTimeが宣言された時だけ動くのです。
tanakashouzoux

2020/05/12 11:13

startTime,elapsedTimeに Date.now() が代入された時、それより前に書かれている全ての startTime,elapsedTimeに Date.now() が代入され d=elapsedTime-startTime のelapsedTime、startTimeにも代入されると思ったのですが、そういうものではないのでしょうか?
m.ts10806

2020/05/12 11:30

ですから d=elapsedTime-startTime の処理、いつ実行されるか確認してください。 あらゆる場所にconsole.log()を仕掛けて。
tanakashouzoux

2020/05/12 23:11

わざわざ大変ご丁寧にありがとうございます! console.log(d) でコンソールにdを表示しようとすると d=elapsedTime-startTime を呼び出し、この elapsedTimeとstartTimeにはDate.now()は代入されていないのですね 本当に何度もご丁寧にありがとうございますm(__)m また機会がありましたら御指導お願い致しますm(__)m
m.ts10806

2020/05/13 00:28

覚えておいてください。 「思った通りに動くのではなく書いた通りに動く。」
guest

0

countUp()の中で、let d=elapsedTime-startTime しないと、
空の変数同士の引き算になっています。

投稿2020/05/12 10:26

okina

総合スコア471

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanakashouzoux

2020/05/12 10:31

ご回答ありがとうございますm(__)m 私の書いたコードではelapsedTimeとstartTimeには何も代入していないという事なのでしょうか?
okina

2020/05/12 10:35

let startTime; let elapsedTime; で、空の変数を宣言して、その後引き算して、dに代入されています。 この時点で、空同士の引き算なのはお分かり頂けるかと思います。 おそらく、その後、startTimeとelapsedTimeに代入することによって、dの値も変わるとお考えでしょうが、そのようなことは起こりません。 let d=elapsedTime-startTimeは、countUp内に移動されてはどうでしょうか?
tanakashouzoux

2020/05/12 10:40

startTimeとelapsedTimeに代入することによって、dの値は変わらないのですか?! startTime、elapsedTimeは let startTime; let elapsedTime; と最初に宣言していても Date.now() が代入されるのに d=elapsedTime-startTime には代入されないのでしょうか?
okina

2020/05/12 10:43

Date.nowの時点で、startTime、elapsedTimeには値が代入され変わりますが、 dは宣言したときのままです。 startTime、elapsedTimeに値が代入された後に、さらにdの値を更新することで、ご希望の動作が実現されます。
tanakashouzoux

2020/05/12 10:58

何度も本当にありがとうございますm(__)m 今試してみたところ確かに上手く行きましたm(__)m ということはstartTimeとelapsedTimeに Date.now() を代入しても、他の変数で使わてれいるstartTime、elapsedTimeには Date.now() は代入されないという事なのでしょうか?
okina

2020/05/12 11:19

後ろにだけ適用されると考えられてもいいんじゃないでしょうか
tanakashouzoux

2020/05/12 22:08

何度もご丁寧にありがとうございますm(__)m okinaさんに教えて頂いた様に「後ろにだけ適用される」と考えていきたいと思います! 本当にありがとうございます! 今後も機会があればご指導下さいm(__)m
m.ts10806

2020/05/12 22:30

「後ろ」でいいんでしょうか。 関数が冒頭に宣言されている場合、「後ろ」でいいのでしょうか。 それで覚えるのは危険だと思います(違う意図で「後ろ」という表現を使っているのでしたら明記してください)
okina

2020/05/13 04:48

@m.ts10806さん ご指摘の通りです。語弊を招く表現でした申し訳ございません。 今回の場合たまたま、そういう動作をしているということでしたが、一般論のように受け取られる表現だと反省しています。 今後より責任も持って、気をつけて参ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問