相信大家都會平時在除錯程式碼時,都會用上 console.log、debugger或者除錯工具。但是一般順手的情況下,我們大多數都會使用console.log,但是console.log真的可信嗎?
結論:console.log在列印引用型別的資料,可能會不準確。在複雜的斷點除錯時,儘可能使用debugger或者除錯工具。
console.log 列印異常var a = { index: 1,}console.log(a)a.index++console.log(a)
以上程式碼分別執行在不同的三種情況下,你會發現比較有意思的地方:
node.js 平臺web 端控制檯未開啟的情況(注:這裡指執行程式碼後再開啟控制檯)web 端控制檯開啟的情況(注:這裡指開啟控制檯進行重新整理)注:以上 web 端經過現代瀏覽器測試發現:chrome、edge、firefox 表現形式一致,與上述類似。safari 在第三種情況下無法進行展開物件。
異常分析web 端為何表現和 node.js 不同我們都知道引用型別,每次使用物件時,都只是使用了物件在堆中的引用。在 node.js 平臺的情況是我們預期的情況,而在 web 端為何會出現如此情況呢?
在 《你不知道的javascript中卷》 中提及過:console.* 方法族並不是JavaScript 正式的一部分,而是由宿主環境新增到JavaScript 中的。因此,不同的瀏覽器和JavaScript 環境可以按照自己的意願來實現。
而在大多數瀏覽器中,console.log 並不會把傳入的內容立即輸出,而是交給瀏覽器進行非同步進行處理,提高效能。
在這裡本人簡單理解為:node.js 平臺為同步列印,瀏覽器平臺為非同步列印。
web 端控制檯是否開啟為何不同未開啟控制檯console.log在大多數瀏覽器中是在控制檯開啟後才起作用,也就是說,當你開啟控制檯時,才會進行列印。
在上述程式碼中,傳進console.log中的參是一個地址,當代碼執行完畢後,開啟控制檯,開始列印,那麼它打印出的實際上是已經做完全部處理後的物件。這就相當於這樣的執行順序:
var a = { index: 1,}a.index++console.log(a)console.log(a)
開啟控制檯開啟控制檯再執行程式碼(即開啟控制檯後進行重新整理),那麼console.log是直接起作用的。瀏覽器有個快照技術,所以我們可以看見我們在控制檯看見的即為正確結果。但是我們地址對應的那個物件還是最終的樣子,所以展開後不同。
解決方案深複製(不推薦)console.log(JSON.parse(JSON.stringify(a)));
對當前的物件進行一次深複製,然後再次輸出。
深複製之後,就不再指向同一處的堆。
debugger 或者 除錯工具利用 debugger 或者 除錯工具 能讓我們避免錯誤,我們應該在平時工作中經常使用。