分享一下今天做的一次實驗!
問題重現(xiàn):打開瀏覽器執(zhí)行以下代碼
var a = {b:{c:1}};
console.log(a);
a.b.c = 2;
控制臺看到打印出來的是什么?{b:{c:2}}對嗎采郎?由此你得出console.log應該是異步的結果。我能告訴你眼見不一定為實么狂魔?你所看到的是錯誤的蒜埋!拿同樣的代碼放到node環(huán)境下跑你就會發(fā)現(xiàn)打印出的是{b:{c:1}}。
是不是感覺很無奈最楷?同一個V8引擎整份,執(zhí)行結果最后居然不一樣!
事實上籽孙,執(zhí)行結果是一樣的烈评,只不過你看到的不一樣罷了!原因就出在瀏覽器控制臺所見不一定為實犯建。
嘗試把打印的代碼換一下讲冠,改為console.log(a.b.c)你會發(fā)現(xiàn)這次是跟node下一致了。我也不想在此延伸瀏覽器控制臺的問題了适瓦,實際上相當于一種懶加載沟启,這也是為什么你可以在控制臺無限查看Object的prototype了。
回到問題本身犹菇,console.log究竟是同步還是異步?我覺得console.log應該和alert一樣是同步的芽卿,會阻塞線程執(zhí)行揭芍。丟一個問題這里:
function test() {
console.log('a'); // 為什么加上console.log之后,執(zhí)行不會報Maximum call stack size exceeded
test();
}
test();
答案:
其實在 console.log 執(zhí)行的時候卸例,chrome 會對 log 的對象求一次值称杨,打印出來是 Object 肌毅,可以繼續(xù)展開的。但當你展開控制臺中的 Object 的時候姑原,chrome 又會對它求一次值悬而,這一次是顯示它的屬性。所以才會有前后打印的東西不一樣的情況發(fā)生锭汛,因為對象引用的實體的值改變了笨奠。
如果把 console.log(a) 改為 console.log(JSON.stringify(a)), 這時就會輸出
{"b":{"c":1}}
是剛開始期望的結果唤殴。