JavaScript 專題之花式表示 26 個字母

先看效果

先來個思考題:git

// 下面這一句會打印什麼呢?
[+[][0] + []][0][1]

咱們直接看效果:github

字母

若是以爲打印一個字母不過癮的話,打印一句話呢?數組

// 注意,在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(+[] == +[]);

若是不能準確的說出以上的結果,或者是想更深刻的理解以上的轉換過程,推薦先看兩篇文章:spa

JavaScript專題之頭疼的類型轉換(上).mdcode

JavaScript專題之頭疼的類型轉換(下).md對象

開始解密

第一個效果:blog

[][0]

由於空數組並不存在第一個元素,因此會打印 undefinedip

第二個效果:

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函數,結果爲:

function find() { [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"字符串

萬能的 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)

其餘

最近新建了公衆號,搜索「冴羽的JavaScript博客」或者 「yayujs」,文章也會第一時間發送,收到推送後依然建議到各平臺閱讀。

冴羽的公衆號

系列博客

JavaScript 系列目錄地址:https://github.com/mqyqingfen...

若是有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。若是喜歡或者有所啓發,歡迎 star,對做者也是一種鼓勵。

相關文章
相關標籤/搜索