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

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

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

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

Q&A

解決済

2回答

405閲覧

格納した値がNaNになってしまう

gyoruo

総合スコア61

JavaScript

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

0グッド

0クリップ

投稿2020/08/23 06:14

ボタンが押された時に値を配列に格納し、もう一度ボタンが押されたら押されたボタンの値を取り除く処理を行いたいのですが、格納するとNaNになり、もう一度ボタンを押すとcost is not definedとエラー表示されます。
どこが原因なのかアドバイスをお願い致します。
格納する時に後からreduceで数値計算するため、Numberでキャストしています。

HTML

1<div class="container"> 2 <button type="button" class="buttons">家賃<br> 3 <span class="costs">80,000</span>円 4 </button> 5 <button type="button" class="buttons">光熱費<br> 6 <span class="costs">5,000</span>円 7 </button> 8 <button type="button" class="buttons">水道代<br> 9 <span class="costs">5,000</span>円 10 </button> 11// 以下省略

JavaScript

1let btns = document.getElementsByClassName('buttons'); 2 let costs = document.getElementsByClassName('costs'); 3 let totalArr = []; 4 5 for (let i = 0; i < btns.length; i++) { 6 btns[i].addEventListener('click', () => { 7 btns[i].classList.toggle('clicked'); 8 9 // ボタンが押された場合の計算用配列の処理 10 if (btns[i].classList.contains('clicked') == true) { 11 let cost = costs[i].innerHTML; 12 totalArr.push(Number(cost)); 13 console.log(totalArr); 14 } 15 else { 16 totalArr.pop(Number(cost)); 17 console.log(totalArr); 18 } 19 }); 20 }

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

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

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

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

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

guest

回答2

0

ベストアンサー

どこが原因なのか

エラーは、メッセージだけでなく発生箇所も教えてくれます。
メッセージ cost is not defined に続く at (filename):(row):(col) がそう。
エラー文は簡潔ながらも重要なヒントを示してくれています。

ご質問コードの原因となりそうな箇所にコメントしてみました(桁揃えしています)。

javascript

1let btns = document.getElementsByClassName('buttons'); 2let costs = document.getElementsByClassName('costs'); 3let totalArr = []; 4 5for (let i = 0; i < btns.length; i++) { 6 btns[i].addEventListener('click', () => { 7 btns[i].classList.toggle('clicked'); 8 9 // ボタンが押された場合の計算用配列の処理 10 if (btns[i].classList.contains('clicked') == true) { 11 let cost = costs[i].innerHTML; // cost は if 文の真となるブロックでのみ有効 12 totalArr.push(Number(cost)); 13 console.log(totalArr); 14 } 15 else { 16 totalArr.pop(Number(cost)); // スコープ内にcost がないので、ここでエラー 17 console.log(totalArr); 18 } 19 }); 20}

reduceで数値計算するため、Numberでキャスト

事前にキャストしなくても reduce() のコールバックで処理することもできます。

javascript

1let total = ["80,000","5,000","5,000"] 2 .reduce((a,s)=>{ 3 a+=s.replace(/,/g,"")|0; 4 return a; 5 }, 0); 6console.log( total ); // 90000

totalArr には条件を満たす値だけを格納(push)し、それ以外はなにもしない。
という方法であれば、 if else で表記された処理も if だけで済みます。

投稿2020/08/25 08:06

AkitoshiManabe

総合スコア5434

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

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

gyoruo

2020/08/26 12:03

ご回答ありがとうございます。 なんだか初心者には難しそうですが、頑張って理解してみます!
guest

0

80,000のように、数値にカンマが含まれているのでNumberによるキャストに失敗してNaNが返されています。

もう一度ボタンを押したときにcost is not definedとなるのは、elst句の中で変数costが定義されていないためです。

さらに、popは配列の最後の要素を取り除くメソッドであるので、引数を指定することはできません。

Array.prototype.pop() - JavaScript - MDN Web Docs - Mozilla

投稿2020/08/23 07:04

編集2020/08/23 07:06
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

gyoruo

2020/08/23 07:53

色々とアドバイスありがとうございます! 取り除く時にspliceなどを用いて頑張ってみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問