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(+[] == +[]);
复制代码

若是不能准确的说出以上的结果,或者是想更深刻的理解以上的转换过程,推荐先看两篇文章:ui

JavaScript专题之头疼的类型转换(上).mdspa

JavaScript专题之头疼的类型转换(下).mdcode

开始解密

第一个效果:cdn

[][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函数,结果为:

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 系列目录地址:github.com/mqyqingfeng…

若是有错误或者不严谨的地方,请务必给予指正,十分感谢。若是喜欢或者有所启发,欢迎 star,对做者也是一种鼓励。

相关文章
相关标签/搜索