Chorme瀏覽器中for迴圈裡面console.log列印二維陣列,展開後資料全部一樣,出現value below was evaluated just now問題
阿新 • • 發佈:2018-12-31
前言
之前在做蟻群演算法研究時,遇到資料爆炸,想列印檢視js資料極限點,於是設定迭代次數為5,預期是每次迭代就列印一次資訊數矩陣,5次迭代列印5組不同的二維陣列,好來檢視每次迴圈中資訊素的變化情況。但是console.log出來的所有資料是一樣的,點選右上角的感嘆號,出現Value below was evaluated just now。與預期不符。
(說明:開始猜想for迴圈列印的東西都一樣,是不是閉包問題,試著往閉包方向去解決,採用let定義,都無效。結果證明此問題不是閉包問題,是console.log取值問題)
然後我模擬該演算法,採用一套簡單邏輯分析其原因。程式碼如下,設定迴圈次數(螞蟻迭代次數為5次),檢視每次迭代資訊數的變化情況。預期情況也是每次迭代就列印一次陣列,5次迭代有5組不同結果:
出現的結果卻是與預期相符的,每次迴圈迭代出現結果不同
但是,當我點開陣列後發現:又出現了Value below was evaluated just now。沒展開的值,如黃色框內是不同的,展開後,如紅色框內的值全是一樣的。究其原因,可以發現其實是在Chrome Console.log()點選展開陣列時,會重新去讀一遍記憶體真實的值然後顯示,所以展開後都是最終值。
因此,在列印二維陣列時,其實如若不展開,他顯示的就是當前值,但是點選展開後,會重新去記憶體讀值,所以展開的值,全是最終值,所以看到所有二維陣列列印的都是一個值的情況。
但是如果不展開,又看不到值,所以本文介紹以下幾種解決方案:
方案一:document.write()輸出顯示
可以得到想要的結果,篇幅問題就不截圖了。
方案二:列印之前克隆物件
function deepClone(obj){ var result,oClass=isClass(obj); //確定result的型別 if(oClass==="Object"){ result={}; }else if(oClass==="Array"){ result=[]; }else{ return obj; } for(key in obj){ var copy=obj[key]; if(isClass(copy)=="Object"){ result[key]=arguments.callee(copy);//遞迴呼叫 }else if(isClass(copy)=="Array"){ result[key]=arguments.callee(copy); }else{ result[key]=obj[key]; } } return result; } //返回傳遞給他的任意物件的類 function isClass(o){ if(o===null) return "Null"; if(o===undefined) return "Undefined"; return Object.prototype.toString.call(o).slice(8,-1); } function sleep(numberMillis) { var now = new Date(); var exitTime = now.getTime() + numberMillis; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } }
可以看到,這樣打印出來的就是每次都不一樣了。