33

我在幫一個同事今天調試一些代碼,我發現谷歌瀏覽器與console.log()一個奇怪的行爲:谷歌瀏覽器的console.log()不一致

看來,如果你:

  1. 創建嵌套的陣列(例如,[345, 「測試」]])

  2. 登錄陣列與console.log()控制檯。

  3. 內陣列值的修改之一,然後console.log()將輸出後的值 - 的當時的console.log()數組的值被執行。

的JavaScript

var test = [[2345235345,"test"]] 
console.log(test); 
test[0][0] = 1111111; 
// outputs: [[1111111,"test"]] 

var testb = {}; 
testb.test = "test"; 
console.log(testb); 
testb.test = "sdfgsdfg"; 
// outputs: {"testb":"test"} 


var testc = ["test","test2"]; 
console.log(testc); 
testc[0] = "sdxfsdf"; 
// outputs: ["test","test2"] 

JSFiddle Example

此行爲不會在Firefox中發生。另外要注意的是,如果我在Chrome調試器中逐行逐行掃描他的代碼,那麼console.log()會輸出正確的值。

有沒有解釋這個奇怪的現象還是隻是谷歌瀏覽器的一個錯誤?

編輯:

我已經縮小的步驟重現不一致console.log()行爲:

如果添加這個腳本到您的網頁:

var greetings=['hi','bye']; 
console.log(greetings); 
setTimeout(function(){ 
    greetings.push('goodbye'); 
},3000); 

,並打開它Chrome 控制檯窗口已打開的新窗口,則console.log()輸出將與加載頁面時不同與控制檯窗口關閉Here's a JSFiddle that demonstrates that

在第一種情況下,在控制檯窗口已打開的情況下,console.log()將輸出數組的當前值(即兩個項目)。

在第二種情況下,在最初關閉控制檯窗口並在之後僅打開頁面加載時,console.log()將輸出數組的較晚值(即三個項目)。

這是Google Chrome的console.log()功能中的一個錯誤?

+0

雖然我不知道怎麼了,究竟這是不是一個錯誤,Chrome,但是這種以某種頻率的東西;您也可以記錄AJAX請求的結果;它追溯地填充它,大概爲了記錄時的清晰度。我太不熟練,開始解釋爲什麼,我剛剛有一個類似的問題困擾着我。但是,任何依賴於正確值的代碼都可以正常運行。 – Jonline

+1

它似乎記錄到控制檯的值是* live *值。引用對象中的任何標量值只有在控制檯輸出中展開有問題的對象後纔會被計算 – Phil

+0

console.log()'的結果會受到類似競爭條件的影響似乎很奇怪。當我通過我的同事代碼時,'console.log()'會輸出我們所期望的值,但在正常執行時,它會輸出一個後來修改的值 - 好像你希望數組的值在精確的時刻'console.log()'被執行。 –

回答

26

經過大量的挖掘,我發現這已被報告爲一個bug,已在Webkit中修復,但顯然還未被拉入Google Chrome。

至於我可以告訴大家,這個問題最初報告如下:https://bugs.webkit.org/show_bug.cgi?id=35801

說明從米奇克萊默2010-03-05 11點37分45秒的PST

1)創建一個對象文字與一個或多個屬性

2)的console.log該對象但離開它關閉(不膨脹它在控制檯)

3)改變的屬性中的一個爲一個新值

現在打開console.log,並且由於某種原因您會看到它具有新值,即使它在生成時的值不同。

我應該指出,如果你打開它,它會保留正確的值,如果不明確。從Chromium開發

響應:

評論#2從帕維爾·費爾德曼2010-03-09 6時33分36秒的PST

我不認爲我們曾經打算修復這個。我們無法將對象轉儲到控制檯中,因此我們也無法偵聽對象屬性的更改以使其始終處於真實狀態。

我們應該確保預期現有的行爲。

一個修復實施兩年半後的2012年8月9日進行的Webkit(http://trac.webkit.org/changeset/125174),但它似乎沒有我們已經進入Chrome瀏覽器呢。

從今天開始,將對象(數組)轉儲到控制檯將導致在控制檯對象擴展(即,延遲)時讀取對象的屬性 。這意味着傾銷相同的對象,而 突變它將很難使用控制檯進行調試。

此更改會在對象/數組的日誌記錄時開始生成對象/數組的簡短預覽,並將此信息傳遞到前端。這隻發生在前端 已經打開時,它只適用於console.log(),而不是實時控制檯交互。

+0

「這意味着傾銷同一個對象,同時突變它將很難使用控制檯進行調試「,我幾個月前才意識到這一點,它讓我瘋狂。 – Fahmi

+0

謝謝。在過去的幾天裏,我一直拉着我的頭髮,試圖弄清楚我的代碼出了什麼問題。這一直是Chrome的一個問題。 – kojow7

+2

它的2017年和它仍然發生嵌套的對象值。我昨天花了幾個小時調試一個編碼插件,因爲它沒有向我顯示這些值,事實證明,當我記錄obj賦值並在之前/之後嵌套obj時,它是鉻。 – OneEyed

3

我找到了這個bug /功能的解決方法。

console.log(JSON.parse(JSON.stringify(myObject))); 

編輯:不幸的是,這不適用於像函數這樣的非原始值。在這裏使用另一個克隆工具

jQuery的例子:

console.log($.extend({}, myObject)); 
+0

好主意!你也可以重寫'toString'函數 –

+0

不幸的是,並不是所有的對象都可以被字符串化。例如'JSON.stringify(document.body)' – ahui