摘要:一個詭異的結果在前端開發中,我們都少不了用來輸出變量和調試。再看下面一個例子圖中的結果,我是在執行了這句話之后才點擊的小三角,然而結果卻沒有變成詭異結果的樣子。
一個詭異的結果
在前端開發中,我們都少不了用console.log來輸出變量和調試。可是在使用它的過程中,偶爾也會出現一些讓我們很費解的行為,如下圖:
是不是很詭異:)
這個詭異的行為是怎么來的呢?其實怪我“斷章取義”了。控制臺上我執行的代碼其實是:
注意到展開的數組旁邊有一個小i,將鼠標移動上去,會出現提示文字:
Value below was evaluated just now.
簡單翻譯一下就是:下面展示的值,是剛剛解釋執行(evaluated,或者你可以用你熟悉的eval函數來理解這個單詞)的結果。
這句話該怎么理解呢?注意到:小i這個提示僅在我們展開數組的時候才會出現,而展開前控制臺上展示的確實是一個空數組[]。因此我們可以將展開前后認為是這個值的兩個狀態。
現在,我們定位到了這個詭異的行為是和展開相關的,那么讓我們來實驗一下展開這個操作會對log出來的值產生什么影響呢?我們將一行一行地在控制臺執行下面三行js代碼:
var a = [] console.log(a) a.push(1, 2, 3, 4, 5)
在執行a.push(1)之前展開[],會得到下面的結果,應該算是一個預期結果:
而在執行a.push(1)之后再展開[],就會得到一開始我給大家看的“詭異”結果了。
現在回過頭來看 Value below was evaluated just now. 這句話,其實說的就是,展開后的值,其實是在你點擊展開小三角的時候,才 “eval” 出來的。
再看下面一個例子:
圖中的結果,我是在執行了a = [1, 2, 3, 4, 5]這句話之后才點擊的小三角,然而結果卻沒有變成“詭異”結果的樣子。這是因為后面我更新數組是直接采用變量賦值的方法,相當于修改了變量a的引用,就和變量的引用賦值一樣,是影響不了a之前所引用的數組的。
也就是說,console.log()在展開時用于eval的,是變量指向的引用而不是變量本身。
試試其他瀏覽器console.log的這個行為并不是chrome限定,在Firefox和Safari中你都能得到同樣的行為。
Firefox:
Safari中由于console.log展不開,因此使用console.dir來展開:
Edge下就不是這樣子了233:
所以如果你不想要這個“詭異”的結果的話,可以用 Edge 調試哦:)
如果不用Edge呢?一個正常的思路是,如果能夠讓console.log直接輸出就是展開的,那么這個行為就不會詭異了。
不過很不幸,我沒有找到能夠做這件事情的API。不過,我們可以借助console.group這個方法,自己造一個展開的結構出來。
/** * expandLog * * @desc 自動展開的 console.log,實現參考: * https://stackoverflow.com/questions/10464844/is-there-a-way-to-auto-expand-objects-in-chrome-dev-tools#27610197 * @author leuisken* @param {Object} obj 需要 log 的對象 */ function expandLog(obj) { if (Array.isArray(obj)) { obj.forEach((value, index) => { console.group(`${index} : ${type(value)}`); expandLog(value); console.groupEnd(); }); } else if (isPlainObject(obj)) { Object.keys(obj) .forEach(key => { const value = obj[key]; console.group(`${key} : ${type(value)}`); expandLog(value); console.groupEnd(); }); } else { console.log(obj); } return; /** * type * * @desc 針對部分常見類型給予更好的輸出方式 * @param {Object} obj 傳入的對象 * @return {string} 類型字符串 */ function type(obj) { const typeofResult = typeof obj; if (typeofResult !== "object") { return typeofResult; } else if (obj === null) { return "null"; } else if (Array.isArray(obj)) { return "Array"; } else if (obj instanceof RegExp) { return "RegExp"; } else if (obj instanceof Date) { return "Date"; } return "Object"; } /** * isPlainObject * * @desc 即:jQuery.isPlainObject * @param {Object} obj 傳入的對象 * @return {boolean} 是否為 PlainObject */ function isPlainObject(obj) { if (!obj || obj.toString() !== "[object Object]" || obj.nodeType || obj.setInterval ) { return false; } if (obj.constructor && !obj.hasOwnProperty("constructor") && !obj.constructor.prototype.hasOwnProperty("isPrototypeOf") ) { return false; } let key; for (key in obj) {} return key === undefined || obj.hasOwnProperty(key); } }
這里寫這個方法只是示個意,估計一般也不會有誰這么做。。其實很無奈,就和console.log、console.dir沒有提供默認展開的API一樣,console.group也沒有提供默認收起的API。。。。
題外話在搜索能否默認展開console.log結果的時候,在Stack Overflow上無意間搜到了這樣一個結果。
https://stackoverflow.com/que...
原來 chrome 的 console,也有自己的 console 啊。。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92175.html
摘要:在第一次循環的時候的值為,此后依次為。所以就出現了上面的問題。此外,在下打印的時候可能與在中打印出現不同的結果。尤其是是這種牽扯到數組下標的盡量不要使用來處理,如果非要使用可以做如下處理以避免如上的問題。 問題復現 var arr = [a, b, c]; var sid = [Go]; for (var key in arr) { sid[key + 1] = arr[key...
摘要:問題復現最近朋友發給我這樣的一個串代碼朋友說,這個輸出不正確。我表示不信,就試了下從結果看,沒毛病啊。朋友說,你展開看看,一看果然有問題縮略狀態的顯示與展開的顯示不同問題思考這個問題的表現是縮略狀態下顯示原數組,展開狀態下顯示排序后的數組。 問題復現 最近朋友發給我這樣的一個串代碼: var arr = [1, 4, 2, 3 ]; console.log(arr); arr.sort...
摘要:函數柯里化關于函數柯里化的問題最初是在忍者秘籍中講閉包的部分中看到的,相信很多同學見過這樣一道和柯里化有關的面試題實現一個函數,使得如下斷言能夠能夠通過簡單說就是實現一個求值函數,能夠將所有參數相加得出結果。方法返回一個表示該對象的字符串。 函數柯里化 ??關于函數柯里化的問題最初是在《JavaScript忍者秘籍》中講閉包的部分中看到的,相信很多同學見過這樣一道和柯里化有關的面試題:...
摘要:本文是對加深對的理解一文的導圖版翻譯中的是一個捉摸不透的東西,它很喜歡變化,很詭異。寫在后面的幾種綁定規則,歸根結底,的套路就是關于幾種模式的等價變換形式,知乎上面有大神解答,猛戳這最后是全圖附上思維導圖的下載鏈接去有道云筆記下載 本文是對《加深對 JavaScript This 的理解》一文的導圖版翻譯 JS中的this是一個捉摸不透的東西,它很喜歡變化,很詭異。擁抱變化,接收詭異...
摘要:在第一次循環的時候并沒有被賦值,所以是,在第二次循環的時候,定時器其實清理的是上一個循環的定時器。所以導致每次循環都是清理上一次的定時器,而最后一次循環的定時器沒被清理,導致一直輸出。 Javascript Evet Loop 模型 setTimeout()最短的事件間隔是4mssetInterval()最短的事件間隔是10ms以上這個理論反正我是沒有驗證過 Exemple 1 --...
閱讀 1756·2021-11-24 09:39
閱讀 1686·2021-11-22 15:22
閱讀 1002·2021-09-27 13:36
閱讀 3230·2021-09-24 10:34
閱讀 3329·2021-07-26 23:38
閱讀 2633·2019-08-29 16:44
閱讀 974·2019-08-29 16:39
閱讀 1104·2019-08-29 16:20