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

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

ただいまの
回答率

88.59%

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

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 272

mezamashiTV

score 6

実現したいこと

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

【ケース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の双方に値が入ってしまうといった現象です。

<div class="list">
  <button type="button">button</button>
  <div class="item_link">
    <!-- <div class="box" data-box='{"name":"taro","id":"1"}'></div> --> 
  </div>
  <div class="item_photos">
    <img src="" data-photo_id="10"><img src="" data-photo_id="20">
  </div>  
</div>
$(document).on('click','button', function(){

    const $list = $(this).closest('.list');

    let linkData = photoData = [];

    const is_link = $list.find('.item_link').children().length === 0 ? false : true;
    const is_photos = $list.find('.item_photos').children().length === 0 ? false : true;            
    console.log('is_link = ',is_link);
    console.log('is_photos = ',is_photos);

    if( is_link && ! is_photos ){
        const data = JSON.parse( $list.find('.item_link .box').attr('data-box') );
        const a = {
            id  : data.id,
            name: data.name
        };
        linkData.push( a );
    }else if( ! is_link && is_photos ){
        $list.find('.item_photos img').each(function(){
            const b = {
                id  : $(this).attr('data-photo_id'),
                name: 'his'
            };
            photoData.push( b );        
        });
    }

    console.log('linkData = ',linkData);
    console.log('photoData = ',photoData);

});

試したこと

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

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

<div class="list">
  <button type="button">button</button>
  <div class="item_link">
    <div class="box" data-box='{"name":"taro","id":"1"}'></div>
  </div>
  <div class="item_photos">
    <!-- <img src="" data-photo_id="10"><img src="" data-photo_id="20"> --> 
  </div>  
</div>


わけがわからないです…

jQeuryバージョン

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

解決策?

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

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

    if( is_link && ! is_photos ){
        const data = JSON.parse( $list.find('.item_link .box').attr('data-box') );
        const a = {
            id  : data.id,
            name: data.name
        };
        linkData.push( a );
        photoData= []; // もう一方を初期化
    }else if( ! is_link && is_photos ){
        $list.find('.item_photos img').each(function(){
            const b = {
                id  : $(this).attr('data-photo_id'),
                name: 'his'
            };
            photoData.push( b );    
        });
        linkData = []; // もう一方を初期化
    }
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+6

let linkData = photoData = [];

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/20 07:59

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

    キャンセル

  • 2020/06/20 10:44

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

    キャンセル

  • 2020/06/23 05:20 編集

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

    キャンセル

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

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る