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

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

ただいまの
回答率

91.46%

  • JavaScript

    10902questions

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

if文の実行順序について

解決済

回答 1

投稿 2017/07/03 15:06

  • 評価
  • クリップ 1
  • VIEW 378

uneco

score 27

JavaScript の基本の「image changer を追加する」にあるコードについてなのですが

var myImg = document.querySelector('img')

myImg.onclick = function () {
  var mySrc = myImg.getAttribute('src')

  if (mySrc === 'images/firefox-icon.png') {
    console.log(myImg) // firefox-icon2.png ...①
    console.log(mySrc) // firefox-icon.png ...②
    myImg.setAttribute('src', 'images/firefox2.png') // ...③
  } else {
    myImg.setAttribute('src', 'images/firefox-icon.png')
  }
}


③を実行する前に、console.logで①と②の中身を見てみました。
予想では①と②の両方ともfirefox-icon.pngだと思っていたのですが、
①だけfirefox-icon2.pngでした。

何故①は③の実行前なのに、console.logで中身を見たときに既にfirefox-icon2.pngになっているのでしょうか。

初歩的な質問ですみません。
回答よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • Lhankor_Mhy

    2017/07/03 16:12

    試していただきたいことがあります。console.log( myImg.cloneNode(true) ); とするとどうなりますか?

    キャンセル

  • uneco

    2017/07/03 23:29 編集

    その場合だと <img src="images/firefox-icon.png" alt="The Firefox logo: a flaming fox surrounding the Earth."> が返ってきました。

    キャンセル

  • Lhankor_Mhy

    2017/07/04 10:03

    では、kreiさんの回答のとおりですね。以前に、私も類似の質問に回答しています。https://teratail.com/questions/5420

    キャンセル

  • uneco

    2017/07/04 10:45

    Lhankor_Mhyさんの過去の質問にあるコードを実際に動かしてみました。私が使っているブラウザはSafariで、最初からWebインスペクタのコンソールを表示した状態でconsole.log(a)を確認すると正しく表示されたのですが、「console.log(a)実行→Webインスペクタのコンソールを開いて確認」の順だとLhankor_Mhyさんの質問にあったような挙動が確認できました。これは、kreiさんの回答にある「コンソールを確認した時点での値を表示する」に確かに当てはまっており、今回のconsole.logの挙動を理解するのにすごく助かりました。有難うございました。

    キャンセル

回答 1

checkベストアンサー

+5

全て通ってからではなく、2の段階でブレークポイントで止めてmyImgの中を見てみてください。
おそらく期待通りのものが入っています。
Javascriptのブレークポイントの設定はGoogleChromeならデベロッパーツールのSourceタブの該当行番号をクリックすることで可能です。デベロッパーツールの便利な機能については検索すればたくさん解説記事がヒットするのでここでは紹介しません。

console.logは常にconsole.logのある位置の変数内容が表示できるわけではありません。
私も何度も騙されたことがありますw

追記

この現象はオブジェクトに対して起こります。console.logに表示される値はコード上のconsole.logのある場所ではなく、ブラウザのコンソールに表示したタイミングでどのような値を持っているかが表示されます。つまりconsole.logの位置より後に代入の行があったとしてもコンソール上で確認するまでに変更が行われた場合変更後の値を目にすることになります。ブレークポイントでは処理自体を止めているので確認までに値が変わることはありません。

この現象のわかりやすい確認方法としては、次の方法があります。
GoogleChromeだとArrayやObjectをコンソール上にだすと、まず1行で変数内容が簡単に表示されており、▶がついていてそれをクリックすると内容を展開して見ることができますよね、これを利用します。
その展開内容も▶が押されたタイミングに変数がどのような値を保持しているかを表示するので1行目の簡易表示と展開内容が違う、なんてことが起こります。

次のようなコードをコンソールに入力してみてください。

var obj={"bool":true}

console.log(obj);

setTimeout(function(){
    obj.bool=false;
}, 5000);

コンソールには次のように表示されていますよね。

Object {bool: true}

すぐに▶を押して開くと次のようになります。

Object {bool: true}
bool:true
▶__proto__:Object

次にもう一度示したコードをコンソールに入力し、5秒以上経ってから▶を押してください。
次のようになるはずです。

Object {bool: true}
bool:false
▶__proto__:Object

投稿 2017/07/03 15:31

編集 2017/07/04 03:58

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/04 03:07

    回答有難うございます。
    もし宜しければもう少し教えてください。

    回答の通り、ブレークポイントで止めてから確認したところ予想通りの値が入っていました。

    「console.logは常にconsole.logのある位置の変数内容が表示できるわけではない」←この部分が調べても出てきません。
    何故「console.logは常にconsole.logのある位置の変数内容が表示できるわけではない」のですか?
    何故ブレークポイントで止めたときとそうでないときとでは結果が違うのですか?

    jsの処理の順番によってconsole.logの表示内容が変わるのかと思い調べたのですが、私の調べた限りではそのような記事は見つけられませんでした、、代わりにsetTimeoutの「指定時間後に処理が実行されるのではなく、実行キューに登録されてから処理が実行される」という記事を見つけて読んだのですが、それは今回のconsole.logの話とはまた別ですよね。

    もし良ければ、console.logの変数の表示内容が変わる理由について教えていただきたいです。
    よろしくお願いします。

    キャンセル

  • 2017/07/04 03:59

    回答に詳細を追記しましたのでご確認ください。

    キャンセル

  • 2017/07/04 10:34

    追記有難うございます!
    追記にあったコードを試したところ、確かにtrueだったのがfalseに表示が変わっていました。setTimeoutについて調べたときに似たコードを見たのですが、kreiさんの
    「ブラウザのコンソールに表示したタイミングでどのような値を持っているかが表示される」
    「コンソール上で確認するまでに変更が行われた場合変更後の値を目にすることになる」
    ↑この部分でやっと今回のconsole.logの挙動について理解することができました。
    追加の質問にも答えていただき、本当に有難うございます。

    キャンセル

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

ただいまの回答率

91.46%

関連した質問

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

  • JavaScript

    10902questions

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