是一種非常容錯的編程語言,許多在其他編程語言中不合法的表達式在中都能正常工作。
這導致了很多奇怪的代碼。你想挑戰它嗎?
挑戰
在這個挑戰中,你將看到20個古怪表達式,并要猜出其輸出結果。
1.
true?+?false
2.
**1.**
3.
[1,?2,?3]?+?[4,?5,?6]
4.
0.2?+?0.1?===?0.3
5.
10,2
6.
!!""
7.
+!![]
8.
true?==?"true"
9.
010?-?03
10.
""?-?-?""
11.
null?+?0
12.
0/0
13.
1/0?===?10?**?1000
14.
true++
15.
""?-?1
16.
(null?-?1)?-?"1"
17.
38?*?4343?*?2342+?(“true”?—?0)
18.
5?+?!5?+?!!5
19.
[]?+?[1]?+?2
20.
1?+?2?+?"3"
結果和分析
true + false
試圖在兩個布爾值之間使用加法運算符(+)時,它們會被轉換為數字。
而且我們都知道true應該被轉換為1,false應該被轉換為0。所以true+false返回1。
[,,,].length
[,,,] 輸出一個有三個空槽的數組。最后一個逗號是尾部的逗號。
你可以這么想。
[,]?????==>?[empty,]
[,,]????==>?[empty,?empty,]
[,,,]???==>?[empty,?empty,?empty,]
所以 [,,,].length 返回3。
[1, 2, 3] + [4, 5, 6]
當你試圖在數組之間使用加法運算符(+)時,它們會被轉換為字符串。
將一個數組轉換為字符串時,數組的 () 方法被調用。()方法是 內部使用的,當一個數組需要顯示為文本時,它將用逗號連接其元素。
[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,34,5,6"
0.2 + 0.1 === 0.3
由于浮點數很難在計算機中準確表示,數學上的0.1和0.2在計算機中只能用近似的數字表示。
0.1+0.2的結果不完全是0.3。不僅僅是,其他編程語言也有同樣的問題。
10, 2
逗號(,)在中也是一個合法的操作符,它評估每個操作數(從左到右),并返回最后一個操作數的值。
因此,10,2返回2
!!""
""是一個空字符串,它是一個虛值。
注意:0、空字符串""、null 和都是虛值。
! 是邏輯上的 "非 "運算符,把 true 變成 false,反之亦然。
如果我們使用兩次!,也就是!!,它將把一個正常的值轉換成一個布爾值。所以!""返回 false。
+!![]
數組都是真值,甚至是空數組。所以!![]將返回true。
!![];?//?->?true
而+號會將真值轉換為其數字表示: 1,所以 +!![] 返回 1。
true == "true"
雙等運算符(==)檢查其兩個操作數是否相等,并返回一個布爾值結果。
根據抽象的雙等比較規則,這兩個值在比較時都被轉換為數字。
true?==?"true"?==>?Number(true)?==?Number("true")?==>?1?==?NaN
所以,ture =="true" 返回false。
010 - 03
這里有一個小小的技巧:如果一個數字以0開頭,那么在中它就被當作一個八進制數字。所以:
010?-?03?==>?8?-?3?==>?5
另外:
** ""--"" **
這看起來是一個錯誤的語法,但它確實工作正常。
空字符串可以被轉換為布爾值false或數字值0。所以 -"" 為 0
null + 0
正如我們之前所說,null是一個虛值。它將被轉換為布爾值false或數字值0。所以結果返回 0。
0/0
這是一個非法的數學表達式。方程0/0沒有任何有意義的數字答案,輸出的結果只是NaN。
1/0 === 10 ** 1000
雖然1/0和之前一樣也是一個非法的數學表達式。但是當除數不是0時,認為這個表達式的結果是。
而10**1000是一個很大數字,JS 無法正確表示這個數字。(中最高的整數值是2^53-1)。所以10 * 1000也被當作無限大()。
無窮大總是等于另一個無窮大,所以1/0 === 10 ** 1000返回 true。
true++
這沒有什么特別的,這只是一個語法錯誤。
""- 1
雖然加法運算符(+)同時用于數字和字符串,但減法運算符(-)對字符串沒有用處,所以將其解釋為數字之間的操作。一個空的字符串會被類型強制為0。
""?-?1?==>?Number("")?-?1?==>?0?-?1?==>?-1
所以 "" — 1 返回 -1
** (null - 1) - "1" **
正如上面所說。
null?==>??0
(null?-?1)?==>?-1
"1"?==>?1
所以 (null — 1) — “1” 返回 -2
38 * 4343 * 2342+ ("true" - 0)
你可能會懷疑JS是如此瘋狂,以至于它將字符串 "true" 轉換為布爾值 true 的數字表示。然而,它并沒有那么瘋狂。實際發生的情況是,它試圖將字符串轉換為數字,但失敗了。
Number("true");?//?->?NaN
在的數字運算中,只要有一個值是NaN,運算的最終結果就一定是NaN。38 * 4343 * 2342只是一個煙霧彈。
5 + !5 + !!5
正如上面所說。
所以:
!5?==>?0
!!5?==>?1
**[] + [1] + 2 **
試圖在數組之間使用加法運算符(+)時,它們會被轉換為字符串。
[]?==>?''
[1]?==>?'1'
[]?+?[1]?==>?'1'
'1'?+?2?==>?'12'
所以結果是'12'。
1 + 2 + "3"
從左到右執行這些操作。當數字3與字符串3相加時,字符串連接將優先進行。
1?+?2;?//?->?3
3?+?"3";?//?->?"33"
總結
坦率地說,這些挑戰并沒有為我膠們編碼技能提供任何價值,所以不應該在實際項目中寫這種代碼
但是,把這些技巧作為朋友和同事之間的一些裝13,不是一件非常有趣的事情嗎?