iT邦幫忙

3

javascript 物件問題

var obj = {};
console.log(obj)
var abc = 456;
var cde = 789;
var ggg= 654;
obj.a=6

請各位大哥看一下程式碼 心裡覺得 obj印出來會是什麼?

為什麼阿會是那個結果阿

明明我就先印出來 不敢相信

看更多先前的討論...收起先前的討論...
dragonH iT邦超人 5 級 ‧ 2020-03-24 15:13:40 檢舉
原本以為你是想問我以為的那個問題

後來發現我誤會了
Han iT邦研究生 1 級 ‧ 2020-03-24 16:13:42 檢舉
@dragonH 是指js的特性嗎XD 同步執行的部份
XD
Han iT邦研究生 1 級 ‧ 2020-03-24 16:14:41 檢舉
我想問一下你在哪邊執行的?
vue專案 的其中一個vue組件
Nick iT邦新手 5 級 ‧ 2020-03-28 23:42:04 檢舉
空的
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
4
fillano
iT邦超人 1 級 ‧ 2020-03-24 16:51:55
最佳解答

變數宣告會先執行,然後是

console.log(obj);
obj.a = 6

這兩行實際上是在一起執行的。

但是我猜console.log(obj)是非同步執行的(這樣效能比較好?),所以他真正印出obj時,下一行已經執行完畢了。

另外,在node.js沒這個現象,而且如果你跑比較複雜的node.js程式(處理資料、分析、需要大量IO等),console.log會嚴重影響效能。所以在node.js環境,恐怕console.log是同步執行的。(不過最近沒在寫,不知道還會不會這樣)

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2020-03-24 17:00:05 檢舉

https://developer.mozilla.org/en-US/docs/Web/API/Console/log

補充一下,MDN有解釋這個問題,請參考「Logging objects」,如果是要記錄物件當下的狀態,他建議這樣做:

console.log(JSON.parse(JSON.stringify(obj)));
fillano iT邦超人 1 級 ‧ 2020-03-24 17:12:26 檢舉

另外,如果你在console.log(obj);之後插入一個會跑夠多時間的運算(例如巢狀的for迴圈),console.log的結果就跟你預期的一樣了。(剛剛測試一下...兩層各一百萬次,然後我只好關瀏覽器了...雖然console.log有正確出來)

froce iT邦大師 1 級 ‧ 2020-03-24 17:23:21 檢舉

js真的是得自己實做才能累積經驗的語言,坑實在太多了。

謝謝這邊大哥熱情討論 我一直以為我是我專案問題 看來我一輩子都不會懂javascript 謝謝

農夫 iT邦新手 5 級 ‧ 2020-03-25 09:55:38 檢舉

遇到傳參考,可以先 deepcopy 再給他.

chaoyuan iT邦新手 5 級 ‧ 2020-03-25 14:56:30 檢舉

應該是跟非同步沒關係,主要是因為call by reference

我其實是在vue專案中 call api 後先印出傳回來的response物件 然後在這個console.log下面修改該物件資料 後來發現竟然是印出我修改後的資料 明明我是先console.log的

之後我在這個api回傳後結果底下 宣告新物件 一樣是印出修改結果 導致我傻眼

1
bizpro
iT邦大師 1 級 ‧ 2020-03-25 14:56:07

不要單獨使用console.log來除錯

console.log不是一個坑,如果您真要用console.log除錯,是您自己挖個坑,您要注意自己不要跳進去,您必須管理物件的生命週期。基本觀念是:console.log都是紀錄物件的最後狀態, 通常要用瀏覽器的除錯器來檢測console.log的值。

如果您用瀏覽器的除錯器,在console.log處設下檢查點,您會看到停止在檢查點的最後狀態,如果您沒有使用除錯器,console.log輸出最終的最後狀態

謝謝 我昨天發現在不同環境測試有不同結果

我其實是在vue專案中 call api 後先印出傳回來的response物件 然後在這個console.log下面修改該物件資料 後來發現竟然是印出我修改後的資料 明明我是先console.log的

bizpro iT邦大師 1 級 ‧ 2020-03-26 15:55:52 檢舉

console.log顯示的是Javascript停止或完成運行後的最終狀態. 我通常用console.log顯示靜態資料,或用來設檢查點的:
console.log("Debug: cp001")
...

瀏覽器的開發者功能太強大了, 著實沒必要用console.log來顯示物件.

0
albert41
iT邦新手 3 級 ‧ 2020-04-11 17:41:33

瀏覽器 console.log 的結果為 Observer (至少 Chrome 是),所以才會看到 obj 的最終結果,實際上確實是先執行 console.log(obj);obj.a = 6;

可以依照上面大大們的建議下中斷點,又或者使用: console.log(JSON.stringify(obj)) 的方式打印出當下實際的狀況。

如果嫌麻煩,自己寫個 plugin 用用吧!

(() => {
    if (window) {
        window.console.copyLog = (data) => {
            console.log(JSON.parse(JSON.stringify(data)));
        }
    }
})();

我要發表回答

立即登入回答