一個有趣和棘手的JavaScript示例列表。 基于個人理解加google翻譯,如有問題請指正,謝謝。 JavaScript是一種很好的語言。它有一個簡單的語法,龐大的生態(tài)系統(tǒng),以及最重要,最偉大的社區(qū)。 同時,我們都知道,JavaScript是一個非常有趣的語言,具有棘手的部分。 他們中的一些可以迅速將我們的日常工作變成地獄,有些可以讓我們大聲笑起來。 WTFJS的原創(chuàng)思想屬于 Brian Leroux. 這個列表受到他的講話的高度啟發(fā) “WTFJS” at dotJS 2012: 目錄 ???? 動機 只是為了好玩 (tips:我翻譯這篇文章同樣也是為了好玩) — “只是為了好玩:一個意外革命的故事”, 托瓦茲 這個列表的主要目的是收集一些瘋狂的例子,并解釋它們?nèi)绾喂ぷ?,如果可能的話?只是因為學習以前不了解的東西很有趣。 如果您是初學者,您可以使用此筆記來深入了解JavaScript。 我希望這個筆記會激勵你花更多的時間閱讀規(guī)范。 如果您是專業(yè)開發(fā)人員,您可以將這些示例視為您公司新手訪問問題和測驗的重要資源。 同時,這些例子在準備面試時會很方便。 無論如何,只是讀這個。 也許你會為自己找到新的東西。 ??? 符號 // -> 用于顯示表達式的結果。 例如: // > 意思是 console.log 或其他輸出的結果。 例如: console.log('hello, world!') // > hello, world! // 只是一個解釋的評論。 例: // Assigning a function to foo constantconst foo = function () {} 例子 [] 等于 ![] 數(shù)組等于一個數(shù)組取反 說明: true 是 false !!'false' == !!'true' // -> true!!'false' === !!'true' // -> true 說明: 考慮一下這一步: true == 'true' // -> truefalse == 'false' // -> false// 'false' 不是空字符串,所以它的值是true!!'false' // -> true!!'true' // -> true baNaNa 用JavaScript寫的老派笑話: 'foo' + + 'bar' // -> 'fooNaN' 說明: 這個表達式可以轉(zhuǎn)化成 'foo' + (+'bar') ,但無法將'bar' 強制轉(zhuǎn)化成數(shù)值 NaN 不是一個 NaN 說明: 規(guī)范嚴格定義了這種行為背后的邏輯: - 如果
Type(x) 不同于 Type(y) , return false. - 如果
Type(x) 數(shù)值, 然后 - 如果
x 是 NaN, return false. - 如果
y 是 NaN, return false. - … … …
— 7.2.14 嚴格模式相等比較 遵循IEEE的“NaN”的定義: 四個相互排斥的關系是可能的:小于,等于,大于和無序。 當至少一個操作數(shù)是NaN時,最后一種情況出現(xiàn)。 每個NaN都要比較無窮無盡的一切,包括自己。 — “對于IEEE754 NaN值的所有比較返回false的理由是什么?” at StackOverflow 它是fail 你不會相信,但... (![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]// -> 'fail' 說明: 將大量的符號分解成片段,我們注意到,以下表達式經(jīng)常發(fā)生: (![]+[]) // -> 'false'![] // -> false 所以我們嘗試將[] 和false 加起來。 但是通過一些內(nèi)部函數(shù)調(diào)用(binary + Operator - >ToPrimitive - >[[DefaultValue] ]),我們最終將右邊的操作數(shù)轉(zhuǎn)換為一個字符串: (![]+[].toString()) // 'false' 將字符串作為數(shù)組,我們可以通過[0] 來訪問它的第一個字符: 現(xiàn)在,其余的是明顯的,可以自己弄清楚! [] 是 true , 但它不等于 true 數(shù)組是一個true ,但是它不等于true 。 !![] // -> true[] == true // -> false 說明: 以下是ECMA-262規(guī)范中相應部分的鏈接: null 是false, 但又不等于 false 盡管 null 是 false ,但它不等于 false 。 !!null // -> falsenull == false // -> false 同時,其他的一些等于false的值,如 0 或 '' 等于 false 。 0 == false // -> true'' == false // -> true 說明: 跟前面的例子相同。 這是一個相應的鏈接: 最小值大于零 Number.MIN_VALUE 是最小的數(shù)字,大于零: Number.MIN_VALUE > 0 // -> true 說明: Number.MIN_VALUE 是 5e-324 ,即可以在浮點精度內(nèi)表示的最小正數(shù),即可以達到零。 它定義了最好的分辨率浮標給你。 現(xiàn)在,整體最小的值是 Number.NEGATIVE_INFINITY ,盡管這在嚴格意義上并不是真正的數(shù)字。 — “為什么在JavaScript中0 小于Number.MIN_VALUE ?” at StackOverflow 函數(shù)不是函數(shù) V8 v5.5或更低版本中出現(xiàn)的Bug(Node.js <= 7)="">=> 所有你知道的關于噪聲 undefined不是function 。是關于這個嗎? // Declare a class which extends nullclass Foo extends null {}// -> [Function: Foo]new Foo instanceof null// > TypeError: function is not a function// > at … … … 說明: 這不是規(guī)范的一部分。這只是一個錯誤,現(xiàn)在它是固定的,所以將來不會有這個問題。 數(shù)組相加 如果您嘗試兩個數(shù)組相加呢? [1, 2, 3] + [4, 5, 6] // -> '1,2,34,5,6' 說明: 會發(fā)生合并。一步一步地,它是這樣的: [1, 2, 3] + [4, 5, 6]// joining[1, 2, 3].join() + [4, 5, 6].join()// concatenation'1,2,3' + '4,5,6'// ->'1,2,34,5,6' 數(shù)組中的逗號 您已經(jīng)創(chuàng)建了一個包含4個空元素的數(shù)組。盡管如此,你還是會得到一個有三個元素的,因為后面的逗號: let a = [,,,]a.length // -> 3a.toString() // -> ',,' 說明: 尾逗號 (有時也稱為“最后逗號”) 在向JavaScript代碼中添加新元素、參數(shù)或?qū)傩詴r有用。如果您想添加一個新屬性,您可以簡單地添加一個新行,而不用修改以前的最后一行,如果該行已經(jīng)使用了后面的逗號。這使得版本控制比較清潔和編輯代碼可能不太麻煩。 — Trailing commas at MDN 數(shù)組相等是一個怪物 數(shù)組進行相等比較是一個怪物,看下面的例子: [] == '' // -> true[] == 0 // -> true[''] == '' // -> true[0] == 0 // -> true[0] == '' // -> false[''] == 0 // -> true[null] == '' // true[null] == 0 // true[undefined] == '' // true[undefined] == 0 // true[[]] == 0 // true[[]] == '' // true[[[[[[]]]]]] == '' // true[[[[[[]]]]]] == 0 // true[[[[[[ null ]]]]]] == 0 // true[[[[[[ null ]]]]]] == '' // true[[[[[[ undefined ]]]]]] == 0 // true[[[[[[ undefined ]]]]]] == '' // true 說明: 你應該非常小心,因為上面!這是一個復雜的例子,但它的描述 7.2.13 Abstract Equality Comparison 規(guī)范部分。 undefined 和 Number 如果我們不把任何參數(shù)傳遞到 Number 構造函數(shù)中,我們將得到 0 。undefined 是一個賦值形參,沒有實際的參數(shù),所以您可能期望 NaN 將 undefined 作為參數(shù)的值。然而,當我們通過 undefined ,我們將得到 NaN 。 Number() // -> 0Number(undefined) // -> NaN 說明: 根據(jù)規(guī)格: - 如果沒有參數(shù)傳遞給這個函數(shù),讓
n 為 +0 ; - 否則,讓
n 調(diào)用 ToNumber(value) - 如果值為
undefined ,那么 ToNumber(undefined) 應該返回 NaN . 這是相應的部分: parseInt 是一個壞蛋 parseInt 它以的怪異而出名。 parseInt('f*ck'); // -> NaNparseInt('f*ck', 16); // -> 15 ** 說明: ** 這是因為 parseInt 會繼續(xù)通過解析直到它解析到一個不識別的字符,f 在 'fuck' 是 15進制 解析 Infinity 到整數(shù)是什么… //parseInt('Infinity', 10) // -> NaN// ...parseInt('Infinity', 18) // -> NaN...parseInt('Infinity', 19) // -> 18// ...parseInt('Infinity', 23) // -> 18...parseInt('Infinity', 24) // -> 151176378// ...parseInt('Infinity', 29) // -> 385849803parseInt('Infinity', 30) // -> 13693557269// ...parseInt('Infinity', 34) // -> 28872273981parseInt('Infinity', 35) // -> 1201203301724parseInt('Infinity', 36) // -> 1461559270678...parseInt('Infinity', 37) // -> NaN 小心解析 null : parseInt(null, 24) // -> 23 說明: 它將 null 轉(zhuǎn)換成字符串 'null' ,并嘗試轉(zhuǎn)換它。 對于基數(shù)0到23,沒有可以轉(zhuǎn)換的數(shù)字,因此返回NaN。 在24,“n” ,第14個字母被添加到數(shù)字系統(tǒng)。 在31,“u” ,添加第21個字母,可以解碼整個字符串。 在37處,不再有可以生成的有效數(shù)字集,并返回 NaN 。 — “parseInt(null, 24) === 23… wait, what?” at StackOverflow 不要忘記八進制: parseInt('06'); // 6parseInt('08'); // 0 說明: 這是因為 parseInt 能夠接受兩個參數(shù),如果沒有提供第二個參數(shù),并且第一個參數(shù)以 0 開始,它將被解析為八進制數(shù)。 true 和 false 數(shù)學運算 我們做一些數(shù)學計算: true + true // -> 2(true + true) * (true + true) - true // -> 3 嗯… 說明: 我們可以用 Number 構造函數(shù)強制轉(zhuǎn)化成數(shù)值。 很明顯,true 將被強制轉(zhuǎn)換為 1 : 一元加運算符嘗試將其值轉(zhuǎn)換成數(shù)字。 它可以轉(zhuǎn)換整數(shù)和浮點的字符串表示,以及非字符串值 true ,false 和 null 。 如果它不能解析特定的值,它將轉(zhuǎn)化為 NaN 。 這意味著我們可以更容易地強制將 true 換成 1 當你執(zhí)行加法或乘法時,ToNumber 方法調(diào)用。 根據(jù)規(guī)范,該方法返回: 如果 參數(shù) is true , 返回 1 。 如果 參數(shù) 是 false 返回 +0。 這就是為什么我們可以進行進行布爾值相加并得到正確的結果 相應部分: HTML注釋在JavaScript中有效 你會留下深刻的印象,
|
|