JavaScript 專題之花式表示 26 個字母
先看效果
先來個思考題:
// 下面這一句會列印什麼呢?
[+[][0] + []][0][1]
我們直接看效果:
[+[][0] + []][0][1]
"a"
如果覺得列印一個字母不過癮的話,列印一句話呢?
// 注意,在Chrome瀏覽器中列印
[[][0] + []][0][5]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][8]+[[[] == []][0] + []][0][2]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]]+[]][0][23]+[[][0] + []][0][3]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][8]+[+[1 + [[][0] + []][0][3] +309][0] + []][0][7]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[][0] + []][0][0]
再來看看效果:
"i love you"
基礎測驗
如果想了解以上是怎麼實現的,先來檢測下自己對JavaScript隱式型別轉換的理解程度:
// 下面這些值都會列印什麼?
console.log(+[]);
console.log(1 + []);
console.log(+undefined);
console.log([] == []);
console.log(+[] == +[]);
如果不能準確的說出以上的結果,或者是想更深入的理解以上的轉換過程,推薦先看兩篇文章:
JavaScript專題之頭疼的型別轉換(上).md
JavaScript專題之頭疼的型別轉換(下).md
開始解密
第一個效果:
[][0]
因為空陣列並不存在第一個元素,所以會列印 undefined
第二個效果:
undefined+ []
undefined + [] 相當於 undefined + "" 結果為"undefined"字串。
這時候已經獲得一個 undefined 字串了,我們只用通過下標就可以取到對應的字母了。
然而,如果我們不用括號,我們怎麼取值呢?這時候,我們就需要利用一個技巧:
第三個效果:
['undefined'][0][0]
這時候我們就獲得了"u"字母,通過改變下標,我們可以獲取u、n、d、e、f、i 共6個字母
是不是很有意思,然而這才只是個開始。
NaN
第一個效果:
+undefined
相當於Number(undefined),結果是NaN
第二個效果:
NaN+ []
相當於NaN + ""結果為NaN字串
第三個效果:
[NaN][0][1]
通過這種方式我們可以取到字母 a。
false
第一個效果:
[] == []
結果自然是false
注意,因為之前兩個例子的鋪墊,或許大家已經漸漸的明白當取出一個值的時候,如果轉成字串,如果取下標的字母了
第二個效果:
// 通過 value + []轉成字串
false + []
第三個效果:
// 通過 [value][0][n] 取字母
['false'][0][0]
我們就可以取出 f 字母
通過這種方式,我們可以取出 "f"、"a"、"l"、"s"、"e"五個字母
true
直接看核心步驟:
+[] == +[]
相當於比較 "" == "",結果自然為 true
剩下的想必大家已經輕車熟路了。
通過以上 4 種方法取到的字母依然有限,我們需要一些其他的方法來獲得更多的字母。
Infinity
注意:在前面我們已經取到了字母 e。
+("1e309")
轉成數字後,相當於 1 乘以 10 的 309 次方,大於JavaScript最大的數,所以結果會是 Infinity,剩下的步驟與上面的相同,以後就不贅述了。
我們可以從中取出 t 和 y
function
注意:到此為止,我們已經獲得了 u n d e f i t r f a l s t y,從中我們可以拼成"find"字串。
[]["find"]
會顯示陣列的find函式,結果為:
functionfind(){ [native code] }
通過這種方法,我們可以取出 c o v。
不過注意:通過這種方式取字母 v 會有相容性問題!!!
神奇的constructor
注意,我們已經有了 17 個字母了,我們現在可以拼出"constructor"!
constructor 可是一個神奇的屬性,因為通過它,我們可以獲得各種型別的值物件的建構函式!
0["constructor"] // function Number() { [native code] }
""["constructor"] // function String() { [native code] }
...
通過以上方式,我們可以取 m、g
也許我們會疑問,""如何表示呢?
[] + [] ===""// true
name
有了 m,我們現在可以拼出 name,可是 name 有什麼用呢?
"to"+""["constructor"]["name"]// "toString"
我們最終的目的是拼出萬能的"toString"字串
廣州vi設計http://www.maiqicn.com 辦公資源網站大全https://www.wode007.com
萬能的 toString
我們之所以拼出 toString,是因為利用 toString 這個方法可以表示出 26個 字母!
這時候,就要隆重介紹下這個平時看起來不起眼,但是在這裡確實最終主角的 toString 方法!
以下引自 W3C school:
作用:
toString() 方法可把一個 Number 物件轉換為一個字串,並返回結果。
用法:
NumberObject.toString(radix)
引數解釋:
radix:表示數字的基數,使 2 ~ 36 之間的整數。若省略該引數,則使用基數 10。但是要注意,如果該引數是 10 以外的其他值,則 ECMAScript 標準允許實現返回任意值
舉個例子:
var number = new Number(10);
number.toString('16');
就是將10用16進位制進行表示,上面的例子列印的結果是"a"。
注意,radix最大可以表示36!!!
var number = new Number(35);
number.toString('36');
列印的字母是 "z"! 用這種方法,我們可以表示剩下的所有字母!
但是我們怎麼利用這個 toString 方法呢?準確的說,我們該怎麼生成一個 number 物件呢?還要拼出 new Number 嗎?
其實都不用!這個時候,就彰顯出了 JavaScript 隱式型別轉換的優秀之處:
35["toString"](36)// z
注意:到了這個時候,我們也不得不使用()了!
到此為止,我們已經可以表示出所有的字母了,有的很輕鬆的就表示出來,有的則有些麻煩,而且顯示也很長,比如字母 p:
25[[[+[] == +[]][0] + []][0][0]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6] + [[] + []][0][[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][3]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[][0] + []][0][1]+[[[] == []][0] + []][0][3]+[[+[] == +[]][0] + []][0][0]+[[+[] == +[]][0] + []][0][1]+[[][0] + []][0][0]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][3]+[[+[] == +[]][0] + []][0][0]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[+[] == +[]][0] + []][0][1]][[[][0] + []][0][1]+[+[][0] + []][0][1]+[0[[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][3]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[][0] + []][0][1]+[[[] == []][0] + []][0][3]+[[+[] == +[]][0] + []][0][0]+[[+[] == +[]][0] + []][0][1]+[[][0] + []][0][0]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][3]+[[+[] == +[]][0] + []][0][0]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[+[] == +[]][0] + []][0][1]]+[]][0][11]+[[][0] + []][0][3]]](27)