javascript
[JavaScript] 多数前端工程师都没注意到的一个关于console.log()的坑
[JavaScript] 多數前端工程師都沒注意到的一個關于console.log()的坑
請閱讀以下代碼并猜測結果:
輸出結果為:
為什么輸出結果不是以下這個?
我要說的坑不是這個,因為相信這個引用類型的賦值問題很多伙伴都能輕松解決。以下提供兩種解決方案:
(方法一),將let obj={}移到for循環中,每次循環創建一個新對象:
能得到預期結果:
(方法二):使用ES6新特性Object.assign,輕松實現深復制,這樣的好處是不用每次都創建一個新對象:
function test() {let obj= {}, arr=[]for(var i = 0; i < 4; i++) {obj.first = iobj.second = i+1obj.three = i+2arr.push(Object.assign({}, obj))}console.log(arr)}test()同樣能得到預期結果:
問題都解決了,那么我說的坑是什么呢?
接下來我們將解決了以上問題的代碼作出以下修改,將console.log移到循環中,如下:
請先預測一下結果是什么再看以下答案。
運行結果為:
每次循環輸出的都是最后的值,是不是有點驚訝?我們再來看一點更驚訝的,在輸出數組前數組一下數組的長度console.log(arr.length),如下:
同樣,先預測運行結果再看以下答案。
運行結果為:
第一次循環輸出數組的長度是1,看起來也是只有一個對象,這很符合預期;但是為什么展開后,里邊會有四個對象?第二次循環數組長度是2,看起來有兩個對象,這符合預期,但是點開后為什么里邊也是有四個對象?這就是我說的坑!!!
原因:
使用console.log()輸出引用類型值時,console.log的實際執行會推遲,相當于“惰性”求值,遇上數組、對象這樣的引用類型就出上面的問題了,也就是我們點擊箭頭打開的時候,才會輸出真正的值,而這時候循環早就已經執行完了,所以輸出的會是循環執行完后的結果!
測試
我們可以將arr轉成非引用類型的數據格式,來證明我們的想法,如下:
顯然,結果已經符合預期,猜測正確!!
完結~ 午休一會~~~
總結
以上是生活随笔為你收集整理的[JavaScript] 多数前端工程师都没注意到的一个关于console.log()的坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 感谢大家支持的话语164个
- 下一篇: 无线路由器上怎么修改wifi密码 如何改