
英文 | https://medium.com/frontend-canteen/20-useless-but-funny-challange-for-javascript-developer-9eea39bb8efb
翻譯 | 楊小愛
由于JavaScript 是一種容錯率極高的程式設計語言,許多在其他程式設計語言中非法的表達式在 JavaScript 中都能正常工作,是不是覺得很神奇?
正是因為JavaScript的這個特點,于是,導緻很多奇怪的代碼,今天我們就一起來看看這些代碼, 我一共總結彙總了20個特别有趣有意思的代碼題,你敢用它去挑戰一下你的朋友同僚嗎?
在這20個代碼題中,我都附加了分析解釋,當然,你也可以自己先試一遍,看看你那邊的結果如何。
好了,我們現在開始吧。
01、true + false
題目如下:
true + false
分析
當你嘗試在兩個布爾值之間使用加法運算符 (+) 時,它們将轉換為數字。
而且我們都知道 true 應該轉換為 1 , false 應該轉換為 0 。是以 true + false 傳回 1 。
輸出結果:
1
02、[,,,].length
[,,,].length
分析
[,,,] 輸出一個包含三個空槽的數組,最後一個逗号是尾随逗号。
你可以這樣想:
[,] ==> [empty,]
[,,] ==> [empty, empty,]
[,,,] ==> [empty, empty, empty,]
是以 [,,,].length 傳回 3。
輸出結果:
3
03、[1, 2, 3] + [4, 5, 6]
[1, 2, 3] + [4, 5, 6]
分析
當我們嘗試在數組之間使用 add operator(+) 時,它們将轉換為字元串。
當我們嘗試将數組轉換為字元串時,将調用數組的 toString() 方法。當需要将數組顯示為文本時,JavaScript 在内部使用 toString() 方法,它将用逗号連接配接其元素。
[1, 2, 3].toString() ==> '1, 2, 3'
[4, 5, 6].toString() ==> '4, 5, 6
是以,[1, 2, 3] + [4, 5, 6]的結果為:
[1, 2, 3] + [4, 5, 6] ==> '1, 2, 3' + '4, 5, 6' ==> "1,2,34,5,6"
04、0.2 + 0.1 === 0.3
0.2 + 0.1 === 0.3
分析
由于浮點數在計算機中很難準确表示,是以數學上的 0.1 和 0.2 在計算機中隻能用近似數來表示。
0.1 + 0.2 的結果并不完全是 0.3。 不隻是 JavaScript; 其他程式設計語言也有同樣的問題。
輸出結果:
false
想了解更多,可以轉到此 StackOverflow 上檢視:https://stackoverflow.com/questions/588004/is-floating-point-math-broken
05、10, 2
10,2
分析
逗号 (,) 在 JavaScript 中也是一個合法的運算符,計算它的每個操作數(從左到右),并傳回最後一個操作數的值。
是以 10, 2 傳回 2。
輸出結果:
2
06、!!""
!!""
分析
"" 是一個空字元串,它是一個假值。
注意:0 、 empty string "" 、 null 和 undefined 都是假值。
!是邏輯 NOT 運算符,将真為假,反之亦然。
如果我們使用 ! 兩次,就是!!,它将普通值轉換為布爾值。是以 !!"" 傳回 false。
輸出結果為:
false
07、+!![]
+!![]
分析
數組都是真值,甚至是空數組。是以 !![] 将傳回 true。
!![]; // -> true
加号字元會将 true 轉換為其數字表示:1
+true; // -> 1
是以 +!![] 傳回 1 。
輸出結果為:
1
08、true == "true"
true == "true"
分析
相等運算符 (==) 檢查它的兩個操作數是否相等,傳回一個布爾結果。
根據抽象相等比較的規則,這兩個值在比較時都轉換為數字。
true == "true" ==> Number(true) == Number("true") ==> 1 == NaN
是以 ture == "true 傳回 false。
false
那麼,這段代碼的結果是什麼?
false == '0'
09、010 - 03
010 - 03
分析
這是一個小技巧:如果一個數字以 0 開頭,它在 JavaScript 中被視為八進制數。
是以
010 - 03 ==> 8 - 3 ==> 5
輸出結果:
5
還有:
- 如果一個數字以 0b 開頭,它在 JavaScript 中被視為二進制數。
- 如果一個數字以 0x 開頭,它在 JavaScript 中被視為十六進制數字。
10、"" - - ""
"" - - ""
分析
這看起來像一個錯誤文法,但它确實工作正常。
空字元串可以轉換為布爾值 false 或數值 0 。
是以 -"" 表示 0
此表達式将傳回 0。
輸出結果:
11、null + 0
null + 0
正如我們之前所說,null 是一個假值,它将被轉換為布爾值 false 或數值 0
是以它會傳回 0。
12、0/0
0/0
這是一個非法的數學表達式,方程 0/0 沒有有意義的數字答案,輸出隻是 NaN。
13、1/0 === 10 ** 1000
1/0 === 10 ** 1000
雖然 1/0 和前面一題一樣,也是一個非法的數學表達式。但是當被除數不為 0 時,JavaScript 認為這個表達式的結果是無窮大。
而 10 ** 1000 這麼大的數字,JavaScript 無法正确表示這個數字。(JavaScript 中的最高整數值為 2^53–1), 是以 10 * 1000 也被視為無窮大。
Infinity 總是等于另一個 Infinity,是以 1/0 === 10 ** 1000 傳回 true。
輸出結果:
true
14、true++
true++
這沒什麼特别的。 這隻是一個文法錯誤。 我們的第一個也是唯一的文法錯誤。
15、"" - 1
"" - 1
分析
雖然加法運算符 (+) 用于數字和字元串,但減法運算符 (-) 對字元串沒有用處,是以 JavaScript 将其解釋為數字之間的操作,空字元串被強制轉換為 0。
"" - 1 ==> Number("") - 1 ==> 0 - 1 ==> -1
是以 "" -1 傳回 -1 :
16、(null - 1) - "1"
(null - 1) - "1"
正如我們之前所說:
null ==> 0
(null - 1) ==> -1
"1" ==> 1
是以 (null - 1) -“1” 傳回 -2 :
輸出結果:
-2
17、38 * 4343 * 2342+(“true” - 0)
38 * 4343 * 2342+ (“true” — 0)
分析
你可能會懷疑 JS 太瘋狂了,以至于它會将字元串文字“true”轉換為布爾值 true 的數字表示。實際發生的是它嘗試将字元串轉換為數字并失敗。
Number("true"); // -> NaN
在 JavaScript 數值運算中,隻要有一個值為 NaN 的值,運算的最終結果一定是 NaN。38 * 4343 * 2342 隻是一個煙霧彈。
輸出結果:
NaN
18、5 + !5 + !!5
5 + !5 + !!5
分析
正如我們之前所說:
- 0 、空字元串 "" 、null 和 undefined 都是假值。
- 非零數字是真值。
是以:
5 + !5 + !!5;
輸出結果為:
6
19、[] + [1] + 2
[] + [1] + 2
正如我們之前所說:當我們嘗試在數組之間使用加法運算符(+)時,它們将被轉換為字元串。
[] ==> ''
[1] ==> '1'
[] + [1] ==> '1'
'1' + 2 ==> '12'
是以結果是 '12' 。
最終輸出結果為:
"12"
20、1+2+"3"
1 + 2 + "3"
分析
JavaScript 會從左到右執行這些操作。當數字 3 與字元串 3 相加時,字元串連接配接将優先。
1 + 2; // -> 3
3 + "3"; // -> "33"
是以,輸出結果為:
"33"
寫在最後
坦率地說,這些代碼題對我們的編碼技能沒有太多價值,并且我們也不應該在實際項目中編寫這種代碼。
但是,将這些技巧作為我們與朋友同僚之間的談點,這也是些代碼的價值,是不是也是一件很有趣的事?
隻是,我在實際生活中,我用這些問題來測試我的朋友後,結果我被一群人毆打了一頓,至于你是否需要用它來測試的朋友或者同僚,請自行決定。