JavaScript 专题之花式表示 26 个字母

简介: 可以表示出所有的字母,有的很轻松的就表示出来,有的则有些麻烦,而且显示也很长。

3.png


先看效果


先来个思考题:


// 下面这一句会打印什么呢?
[+[][0] + []][0][1]
复制代码


我们直接看效果:


0.png


如果觉得打印一个字母不过瘾的话,打印一句话呢?


// 注意,在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]
复制代码


再来看看效果:


01.png


基础测验


如果想了解以上是怎么实现的,先来检测下自己对 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函数,结果为:


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,对作者也是一种鼓励。



目录
相关文章
|
1月前
|
前端开发 JavaScript 安全
前端JS实现密码校验键盘横竖、26字母、相同字母、相同数字、密码包含用户名、数字 字母不能连续 不能相同三个、不能横向 竖向 连续三个 包含字符、不能有中文符号
该 JavaScript 代码实现了一个严格的密码校验功能,确保密码满足多种安全要求,包括长度、字符类型、不包含中文及特殊字符、不与用户名相似等。通过多个辅助函数,如 `validateFormat` 检查密码格式,`isHasChinaCharFun` 检测中文符号,`getCharAll` 生成键盘组合,以及 `checkPasswordFun` 综合验证密码的有效性和安全性。此工具对于提高用户账户的安全性非常有用。
25 0
用html+javascript打造公文一键排版系统14:为半角和全角字符相互转换功能增加英文字母、阿拉伯数字、标点符号、空格选项
用html+javascript打造公文一键排版系统14:为半角和全角字符相互转换功能增加英文字母、阿拉伯数字、标点符号、空格选项
|
4月前
|
JavaScript 搜索推荐
js 混合排序(同时存在数字、字母、汉字等)
js 混合排序(同时存在数字、字母、汉字等)
244 0
|
6月前
|
JavaScript
JS生成随机的由字母数字组合的字符串
JS生成随机的由字母数字组合的字符串
|
6月前
|
JavaScript
js字母大小写转化——两种方式
js字母大小写转化——两种方式
|
JavaScript
JS字符串中的第一个字母大写(两种方法)
JS字符串中的第一个字母大写(两种方法)
89 0
|
JavaScript 前端开发
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
|
JavaScript 前端开发
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
|
JavaScript 索引
Vue 模拟通讯录列表用 js-pinyin 获取汉字首字母,形成字母索引
Vue 模拟通讯录列表用 js-pinyin 获取汉字首字母,形成字母索引
246 0
Vue 模拟通讯录列表用 js-pinyin 获取汉字首字母,形成字母索引