1. 程式人生 > >Chorme瀏覽器中for迴圈裡面console.log列印二維陣列,展開後資料全部一樣,出現value below was evaluated just now問題

Chorme瀏覽器中for迴圈裡面console.log列印二維陣列,展開後資料全部一樣,出現value below was evaluated just now問題

前言

之前在做蟻群演算法研究時,遇到資料爆炸,想列印檢視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;
    }
}

可以看到,這樣打印出來的就是每次都不一樣了。 

方案三:Json.Stringify轉換成字串