yamakawacho
@yamakawacho

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

javascriptとブラウザのコンソールについて

解決したいこと

お世話になります。

以下のhtmlを実行した時の挙動について、お教えください。

<body>
	<div id="content"></div>
</body>

<script>
	var tag = document.createElement('p');	//[1]

	tag.id = 'あ';							//[2]
	tag.textContent = "あ" ;				//[3]
	console.log("tag-id1:" , tag.id);		//[4]
	console.log("tag1:"    , tag);			//[5]

	tag.id = 'い';							//[6]
	tag.textContent = "い" ;				//[7]
	console.log("tag-id2:" , tag.id);		//[8]
	console.log("tag2:"    , tag);			//[9]
</script>

もちろん画面には何も表示されないのですが、
コンソールで見ると、[5]の結果が、「い」になります。
期待しているのは、「あ」です。ちなみに[4]の結果は「あ」です。

キャプチャ2.JPG

参照渡し的なあたりに原因があるのかと、かなり悩んだのですが、chromeで何度も更新していると、時折り表示が変わることが分かりました。値も変わりますが、表示の様式も変わります。
edgeも同様です。

キャプチャ.JPG

さらに、firefoxだと、逆に「あ」の事が多いですがやはり100%ではありません。

この現象はいったい何なのでしょうか?

この様なコードの書き方をした場合、なにかしらの事が保証されず、都度の状況やブラウザの仕様に拠って結果が不定となってしまうのではないかと想像しているのですが、どこに問題があるのでしょうか?

よろしくお願いいたします。

0

3Answer

以下の記事が参考になりませんか?

オブジェクトのログ出力
https://developer.mozilla.org/ja/docs/Web/API/console/log#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E3%83%AD%E3%82%B0%E5%87%BA%E5%8A%9B

"console.log(obj) を使わず、 console.log(JSON.parse(JSON.stringify(obj))) を使用してください。"

"これにより、ログを記録した瞬間の obj の値を確実に見ることができます。こうしないと、多くのブラウザーでは値が変化したときに常に更新されるライブビューになります。これは望むことではないかもしれません。"


【訂正】

tag は JavaScript オブジェクトではなくて html element なので、

console.log(tag) を使わず、 console.log(tag.outerHTML) を使用してください。

というのが正しかったです。

上の MDN のドキュメントに書いてある "多くのブラウザーでは値が変化したときに常に更新されるライブビューになります" というのは html element (DOM) でも同じということのようです。


【追記】

念のため検証してみました。以下のコードで、

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <div id="content"></div>
</body>
<script>
    var tag = document.createElement('p');	//[1]

    tag.id = '';				//[2]
    tag.textContent = "";			//[3]
    console.log("tag-id1:", tag.id);		//[4]
    console.log("tag1:", tag.outerHTML);	//[5]
    
    tag.id = '';				//[6]
    tag.textContent = "";			//[7]
    console.log("tag-id2:", tag.id);		//[8]
    console.log("tag2:", tag.outerHTML);	//[9]
</script>
</html>

結果は以下の通りとなります。

devtool.jpg

5Like

Comments

  1. @yamakawacho

    Questioner

    なんとー!!!
    そういう事だったのですね?!

    "これらのブラウザーで記録されるのはオブジェクトへの参照です。そのため、 console.log() を呼び出した時点でのオブジェクトの「値」が表示されるのではなく、内容を見るために開いた時点での値が表示されます。"

    なんというか、反則というか...。そのような仕様にする理由があるのでしょうけど、いったいどのような合理的な理由があるのでしょうかね。

    いやいや、大変勉強になりました。
    ありがとうございました。
    また、検証までして頂き重ねてお礼申し上げます。

  2. すごくいい答えだと思います。
    勉強になりました。

window.addEventListener("load", async (event) => {
  var tag = await document.createElement('p');	//[1]
  tag.id = await 'あ';							//[2]
  tag.textContent = await "あ" ;				//[3]
  await console.log("tag-id1:" , tag.id);		//[4]
  await console.log("tag1:"    , tag);			//[5]

  tag.id = await 'い';							//[6]
  tag.textContent = await "い" ;				//[7]
  await console.log("tag-id2:" , tag.id);		//[8]
  console.log("tag2:"    , tag);	
});

とすると期待通りになるのではないかと思います。

3Like

Comments

  1. @yamakawacho

    Questioner

    ありがとうございます!
    consoleの完了する前に、次の処理が追い越してしまったという事ですね!

    そう納得して試してみたのですが、結果は変わりませんでした。(TT)
    遅延・非同期的な問題ではないという事ですかね???

  2. 横レス失礼します。

    consoleの完了する前に、次の処理が追い越してしまったという事ですね!

    そういうわけではないです。javascript オブジェクトや html 要素 (DOM) に関しては、内容を見るために Console を開いた時点での値が表示されるからだそうです。詳しくは私の回答を見てください。

  3. @yamakawacho

    Questioner

    @SurferOnWwwさんありがとうございます。
    これから確認させて頂きます。

console.log("tag1:"    , tag);			
alert("tag1:", tag);
tag.id = 'い';
console.log("tag1:"    , tag);			
var tag = document.createElement('p')
tag.id = 'い';

としても同じでしょうか?

さて、

console.log("tag1:" , tag);
の"tag1:"のタイプを確認してください。

次にtagのタイプを確認してください。

更に、tag.idやtag.textContentのタイプを確認してください。

javaScriptはタイプで得られたレベルの値をconsole.logの引数として渡しています。

その後、consoleが変換しています。

1Like

Comments

  1. @yamakawacho

    Questioner

    ありがとうございます!
    確認をしている途中で、@SurferOnWww さんの回答を得て、原因が判明しました。
    いったい何故?!?!...という感じです。

    ちなみに、ご提示いただいたテストもやってみました。
    修正後のコードの全体がちょっとはっきりしなかったので、もしかしたら違っているかもしれませんが・・・。

    <script>
    	var tag = document.createElement('p');	//①
    
    	tag.id = 'あ';							//②
    	tag.textContent = "あ" ;				//③
    	console.log("tag-id1:" , tag.id);		//④
    	console.log("tag1:"    , tag);			//⑤
    
    	alert("tag1:", tag);
    	tag.id = 'い';
    
    	console.log(typeof "tag-id1:");			//string
    	console.log(typeof tag);				//object
    	console.log(typeof tag.id);				//string
    	console.log(typeof tag.textContent);	//string
    
    </script>
    

    結果は、
    テスト31.JPG

    allert は、空白でした。
    もう一つ。

    <script>
    	var tag = document.createElement('p');	//①
    
    	tag.id = 'あ';							//②
    	tag.textContent = "あ" ;				//③
    	console.log("tag-id1:" , tag.id);		//④
    	console.log("tag1:"    , tag);			//⑤
    
    	var tag = document.createElement('p');
    	tag.id = 'い';
    
    	console.log(typeof "tag-id1:");			//string
    	console.log(typeof tag);				//object
    	console.log(typeof tag.id);				//string
    	console.log(typeof tag.textContent);	//string
    
    </script>
    

    結果は、
    テスト31a.JPG

    いろいろ勉強になりました。
    ありがとうございました!

  2. @yamakawacho

    Questioner

    2つ目のテストの結果で、ふと、気になりました。

    2つ目の、
    var tag = document.createElement('p'); 
    tag.id = 'い';
    によって、tagの中身は、2つ目のdocument.createElement('p')のアドレスに書き換わっていると思います。にもかかわらず、console.logの結果として、
    <p id="あ">あ</p>
    になるという事は、
    "内容を見るために開いた時点での値が表示されます"
    といいつつも、
    『開いた時点のtagの示すアドレスの、開いた時点の内容』ではなく、
    『console.logを実行した時のtagの示すアドレスの、開いた時点の内容』
    という事になるのですかね・・・。(ちょっと自信ないですが・・)

    いずれにしても勉強になりました。
    ありがとうございました。

  3. alertの前の結果が予想外ですが、alert画面は期待値では?

    p.s. console.logだけでなく、たまには
    console.info,console.errorとかも使ってあげて下さい。他に10個位あります

  4. @yamakawacho

    Questioner

    ありがとうございます。
    当初の想定で考えると、alertには「あ」を期待しておりました。
    consoleにも種類があるのですね。
    使いこなせるように調べていきたいと思います。

Your answer might help someone💌