wtf.js – JavaScript 令人又愛又恨之處

JavaScript 諸多怪異不合理的地方讓人頭痛

還有一個 Github 專案 – wtfjs
https://github.com/brianleroux/wtfjs

讓人分享一些 JavaScript 讓人覺得 What The Fuck 的經驗
例如下面這個:

Math.max(3, 0); // 3
Math.max(3, {}); // NaN
Math.max(3, []); // 3
Math.max(3, true); // 3
Math.max(3, 'foo'); // NaN
Math.max(-1, null); // 0
Math.max(-1, undefined); // NaN

還有這個

[] + [] // ""
[] + {} // [object Object]
{} + [] // 0
{} + {} // NaN

很莫名XD
更多瘋狂的問題是我在 Stackoverflow 看到的問題

1. Can you explain why ++[[]][+[]]+[+[]] = “10”?

http://stackoverflow.com/questions/7202157/can-you-explain-why-10

++[[]][+[]]+[+[]]  // 這串居然會等於 10 ...wtf

步驟一. 按照下面強者的回覆我們必須先把可以拆開的 + 前後拆開來看

++[[]][+[]]
+
[+[]]

再來下一個關鍵是

+[] === 0

ㄜ … 為什麼會這樣?
因為 + 當作一元運算子也就是"正號"時,會把後面 toNumber
變成數字之前必須先用到陣列的 toString,而空陣列 toString 會變成 ""

+[] === +""

最後空字串 toNumber 會是 0,所以

+"" === 0

步驟二. 把 +[] 給換成0

++[[]][0]
+
[0]

步驟三. 分析換掉 ++[[]][0]

[0]是對陣列取第一個元素,所以[[]][0] 會得到裡面的陣列 []
++ 是做先遞增,遞增總是會回傳數字
所以 ++[[]][0] 等同於 +([] + 1)

+([] + 1)
+
[0]

步驟四. 分析換掉 +([] + 1)

[] 做加法時會先 toString 變成 ""

+([] + 1) === +("" + 1)

"" + 1 時,會讓 1 toString 變成 "1"

+("" + 1) === +("1")

最後字串加上一元運算子的正號又強迫變回數字

+("1") === 1

所以算式變成

1
+
[0]

步驟五. 把 [0] 換掉

[0] 要相加會先 toString 變成 "0"

1
+
"0"

步驟六. 相加

與字串相加會先 toString1 變成 "1" ,所以最後答案是 "10"  !!!!

"1" + "0"   // "10"

2.(![]+[])[+[]]… Explain why this works

http://stackoverflow.com/questions/4170978/explain-why-this-works?lq=1

alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]);  // output "fail"

這一長串的也是蠻難去解…

步驟一. 拆開

(![]+[])[+[]]
+
(![]+[])[+!+[]]
+
([![]]+[][[]])[+!+[]+[+[]]]
+
(![]+[])[!+[]+!+[]]

步驟二. 分析 (![]+[])

[] 是 truthy值,所以

![] === false

false 跟 [] 相加要做 toString轉換,前面有提到過 [] toString 就是 ""

false + "" === "false"

所以

(![]+[]) === "false"

又因為前面提到過的 [+[]] === [0]

(![]+[])[+[]] === "false"[0]  // f

步驟三. 分析 [+!+[]]

+[] 前面有說過等同 0
0 是 falsy 值,! + [] 也就是 !0 會變成 true

! + [] === true

在一個正號強迫 toNumber, true 會變成 1

+true === 1

所以

(![]+[])[+!+[]] === "false"[1]  // a

步驟四. 分析 [!+[]+!+[]]

拆開

!+[]
+
!+[]

從上面的經驗很明顯的可以直接轉換成

true + true // toNumber 1 + 1 -> 2

所以

(![]+[])[!+[]+!+[]] === "false"[2]  // l

步驟五. 分析最後的  ([![]]+[][[]])[+!+[]+[+[]]]

拆成

([![]]+[][[]])
[+!+[]+[+[]]]

依照前面的經驗可以很快轉換的求出部分

([![]]    // [false]
+
[][[]])   // undefined
[+!+[]    // 1
+
[+[]]]    // [0]

所以可以知道最後的這個部分是

"falseundefined"[10]  // i

全部的四個字就是 “fail" !!

文章寫到這都快發瘋了說….

但又看到有文章是在寫如何用 +![]{} 來湊出 a~z..
http://sla.ckers.org/forum/read.php?24,33349,33405

可以不要這樣殘害自己嗎XDD

最後送上這個病入膏肓的 JavaScript Code to +![]{} 的轉換器 – jsfuck….
有才的人實在太多了啊
http://www.jsfuck.com/

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s