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

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

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

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

Q&A

解決済

2回答

606閲覧

【JS】コード完成後の、挙動が理解できない部分(if文)の理解をサポートいただけませんか?

Keisuke..08

総合スコア11

JavaScript

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

0グッド

0クリップ

投稿2022/03/17 08:59

とある動画を参考にJSのコードを模写し、自己流も交えて、自分だけで書ける手前まで来ました。一箇所だけ理解できないコードがあり、教えて頂きたいと思います。

それは、「 if(todo && todo.completed){ //←この部分です。」と記載がある、VSCodeで開いたところの27行目になります。

todoを除いて、「if(todo.completed)」だけで記載した場合でも動くと思ったのですが、下記のようなエラーが表示されます。(「if(todo.completed)」だけの方が、感覚的に正しいと感じてしまいます。)

なぜ、「if(todo.completed)」だけだとエラーがでるのでしょうか?

私は、以下のように考えて、理解できておりません。

→todo.completedが「true」か「false」ででるなら、当然todoも参照している。そのため、add関数で作成されているliタグに、trueであれば「text-decoration-line-through」を追加し、「text-decoration-line-through」を追加しないとできるのではないだろうか、、

エラー文

Uncaught TypeError: Cannot read properties of undefined (reading 'completed') at add (practice_2.js:27:13)

JavaScript

1form = document.getElementById("form"); 2input = document.getElementById("input"); 3ul = document.getElementById("ul"); 4 5todos = JSON.parse(localStorage.getItem("todos")); 6 7form.addEventListener("submit", function (event){ 8 event.preventDefault(); 9 if (input.value.length > 0){ 10 add(); 11 } 12}); 13 14if(todos){ 15 todos.forEach(todo=>{ 16 add(todo) 17 }); 18} 19 20function add(todo){ 21 const li = document.createElement("li"); 22 if (todo){ 23 li.innerText = todo.text; 24 }else{ 25 li.innerText = input.value; 26 } 27 if(todo && todo.completed){ //←この部分です。 28 li.classList.add("text-decoration-line-through"); 29 } 30 li.classList.add("list-group-item"); 31 ul.appendChild(li); 32 input.value =""; 33 34 li.addEventListener("contextmenu", function (event){ 35 event.preventDefault(); 36 this.remove(); 37 saveData(); 38 }); 39 40 li.addEventListener("click", function (){ 41 li.classList.toggle("text-decoration-line-through"); 42 saveData(); 43 }); 44saveData(); 45} 46 47function saveData(){ 48 const lists = document.querySelectorAll('li'); 49 let todos = []; 50 51 lists.forEach(list =>{ 52 let todo = { 53 text: list.innerText, 54 completed: list.classList.contains("text-decoration-line-through") 55 } 56 todos.push(todo); 57 }); 58localStorage.setItem("todos", JSON.stringify(todos)) 59} 60

html

1コード<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> 8 <title>Documentの名前を変える</title> 9</head> 10<body class="bg-light"> 11 12 <div class="container w-75"> 13 <h1 class="text-center text-info my-4">TODO</h1> 14 <form id="form" class="mb-4"> 15 <input type="text" id="input" class="form-control" placeholder="TODOを入力" autocomplete="off"> 16 </form> 17 <ul class="list-group text-secondary" id="ul"></ul> 18 </div> 19 20 practice.js 21 22 <script src = "practice_2.js"></script> 23 24</body> 25</html>

質問をすることにまだ慣れていないので、「もっとピンポイントで質問するべき」などご意見も頂戴いただけると尚幸いです。

長文お読み頂きありがとうございました。

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

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

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

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

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

guest

回答2

0

ベストアンサー

js

1 if (input.value.length > 0){ 2 add(); 3 }

ここで引数なしで add() を呼んでいるため、add() 内で引数 todoundefined という値になります。
undefinedcompleted プロパティにアクセスすることはできないため、undefined の場合は除外するために todo && を付けるのでしょう。

私だったら、ここの呼び出しを add({text:input.value, completed:false}) にして、add() 内で todoundefined になるケースを排除します。

投稿2022/03/17 09:09

編集2022/03/17 09:11
int32_t

総合スコア20882

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

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

Keisuke..08

2022/03/17 10:48 編集

submitをしてadd()関数を使用した場合には、todoは渡されていないため、真偽を判定することができないということなのですね。 下記、記述頂いた部分に関して、ハッシュを直に引数に入れられるとは知りませんでした。 学習を進めたいと思います。 add({text:input.value, completed:false}); ありがとうございます!!
guest

0

なぜ、「if(todo.completed)」だけだとエラーがでるのでしょうか?

todo自体にnullあるいはundefinedが来た場合、ご提示のようにtodo.completedは参照しただけでエラーとなります。この可能性を除外する必要がある、ということです。

投稿2022/03/17 09:03

maisumakun

総合スコア145184

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

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

maisumakun

2022/03/17 09:05 編集

> todo.completedが「true」か「false」ででるなら todoそのものがnullやundefinedの場合は「ReferenceError」となり、「真偽を判定できる値を返す」という前提条件が成立しません。
maisumakun

2022/03/17 09:07

add();と引数無しで呼び出した場合、仮引数のtodoはundefinedとなります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問