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

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

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

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

1回答

1415閲覧

JSで条件分岐を無視して値が入ってしまいます

mezamashiTV

総合スコア6

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/06/19 22:15

編集2020/06/19 22:30

###実現したいこと
以下条件を実現したいです。

【ケース1】.item_linkに子要素が存在するとき
linkDataに値を入れたい

【ケース2】.item_photosに子要素が存在するとき
photoDataに値を入れたい

※ちなみに.item_link.item_photosは片方しか存在しません。

###発生している問題
かなり謎な現象です。

ケース1と2はis_linkis_photoで条件分岐しているのにも関わらず、どちらのケースでもlinkDataphotoDataの双方に値が入ってしまいます。

###該当のソースコード
以下を実行してみてください。ケース2です。

.item_photosにしか子要素は存在しませんので、判定は問題なく
is_link = false
is_photos = true
とコンソールに出ます。

しかし、linkDataphotoDataの双方に値が入ってしまうといった現象です。

html

1<div class="list"> 2 <button type="button">button</button> 3 <div class="item_link"> 4 <!-- <div class="box" data-box='{"name":"taro","id":"1"}'></div> --> 5 </div> 6 <div class="item_photos"> 7 <img src="" data-photo_id="10"><img src="" data-photo_id="20"> 8 </div> 9</div>

js

1$(document).on('click','button', function(){ 2 3 const $list = $(this).closest('.list'); 4 5 let linkData = photoData = []; 6 7 const is_link = $list.find('.item_link').children().length === 0 ? false : true; 8 const is_photos = $list.find('.item_photos').children().length === 0 ? false : true; 9 console.log('is_link = ',is_link); 10 console.log('is_photos = ',is_photos); 11 12 if( is_link && ! is_photos ){ 13 const data = JSON.parse( $list.find('.item_link .box').attr('data-box') ); 14 const a = { 15 id : data.id, 16 name: data.name 17 }; 18 linkData.push( a ); 19 }else if( ! is_link && is_photos ){ 20 $list.find('.item_photos img').each(function(){ 21 const b = { 22 id : $(this).attr('data-photo_id'), 23 name: 'his' 24 }; 25 photoData.push( b ); 26 }); 27 } 28 29 console.log('linkData = ',linkData); 30 console.log('photoData = ',photoData); 31 32});

###試したこと
上記の通りですがis_linkis_photoでの判定をコンソールに出すということを試しまして、これできちんと判定できているのに、なぜ?といった感じで、ほかに試すことが思いつきません。

あとはHTMLのコメントアウトを逆にしました↓が、すると逆の値が双方に入りました。

html

1<div class="list"> 2 <button type="button">button</button> 3 <div class="item_link"> 4 <div class="box" data-box='{"name":"taro","id":"1"}'></div> 5 </div> 6 <div class="item_photos"> 7 <!-- <img src="" data-photo_id="10"><img src="" data-photo_id="20"> --> 8 </div> 9</div>

わけがわからないです…

###jQeuryバージョン
上記は3.4.1の最新ですが、バージョンはあまり関係なく古いものでも同様でした。

###解決策?
無理やりもう一方を初期化すると解決しました↓が、そもそも初期化しないといけないことに納得できません。条件分岐を超えてしまうことが問題なので、その点での解決策を知りたいです。

アドバイス宜しくお願いいたします。

jQuery

1 if( is_link && ! is_photos ){ 2 const data = JSON.parse( $list.find('.item_link .box').attr('data-box') ); 3 const a = { 4 id : data.id, 5 name: data.name 6 }; 7 linkData.push( a ); 8 photoData= []; // もう一方を初期化 9 }else if( ! is_link && is_photos ){ 10 $list.find('.item_photos img').each(function(){ 11 const b = { 12 id : $(this).attr('data-photo_id'), 13 name: 'his' 14 }; 15 photoData.push( b ); 16 }); 17 linkData = []; // もう一方を初期化 18 }

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

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

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

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

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

guest

回答1

0

JavaScript

1let linkData = photoData = [];

このようにすると、両者には同じ配列オブジェクトが代入されます。片方に値を追加すれば、それはもう片方でも影響してしまいます。let linkData = [], photoData = [];のように別に配列を作ってください。

投稿2020/06/19 22:42

maisumakun

総合スコア145184

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

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

mezamashiTV

2020/06/19 22:49

どうもありがとうございます。これは知りませんでした…。 異なる名前なのに、同じオブジェクトとして扱われるということですよね? どのようなメリットや使い道があるのでしょうか。混乱するだけのように思いませんか?
maisumakun

2020/06/19 22:53

C++とPHP(配列はオブジェクト型と全く別扱い)を除いて、配列がオブジェクトとして扱われる言語の多くにこのような挙動は共通します。
amadablam

2020/06/19 22:53

横から失礼。「異なる名前なのに、同じオブジェクトとして扱われる」というよりも「同じオブジェクトに異なる名前を付けている」コードを書いているからそうなるだけです。オブジェクトの代入という考え方が誤解を生みます。「オブジェクトの参照」の代入と考えれば筋が通るでしょう。
mezamashiTV

2020/06/19 22:56

maisumakun様 そうなのですね。ありがとうございます。多言語に行く際には注意いたします。
mezamashiTV

2020/06/19 22:59

amadablam様 なるほどありがとうございます。 それにしても「同じオブジェクトに異なる名前が付けられること」というのは、どのようなメリットがあるのでしょうか。 私としては「異なる名前をつけたら、後者の名前で上書きされる」という挙動の方がわかりやすいような気が致します。
Daregada

2020/06/20 01:44

後者の名前で上書きされるとは、前者の名前ではアクセスできなくするということかな。それでは困る場合が大量にあるので、多くのプログラミング言語ではそういう設計にはなっていません。
amadablam

2020/06/22 20:22 編集

a = b = {}; のコードでは オブジェクト {} の参照(メモリ・アドレス)が変数 b に代入され、変数 b の値(つまり {} の参照)が 変数 a に代入されます。「代入式の両辺は等しい」ことを考えると、この a, b, {} がすべて同じなのは論理一貫していて「わかりやすい」と思うのですが。a = b = {}; のコードは、b = {}; a = b; と2つに分けて考えることができますが、これは b = {}; function f(a) {} というコードがあったときに f(b); のように f関数に実引数 b を渡して呼び出すことと等価です。ここでf関数内では a という名前で元の {} を扱うことができ、関数呼び出しが戻れば、呼び出し側のコードで同様に {} を扱うことができます。オブジェクト指向において厳密な実体を指す意味では、オブジェクトとは「インスタンス」であり、インスタンスとは「一意な実体」としてシステムの中で文字通りユニークな存在として扱われるのが自然な考え方です。インスタンスのコピーを作成して、コピーのみに何か操作をするというのはむしろ自然ではないでしょう。現実世界で言えば、あちこちにクローンが存在してしまうような状況ですよね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問