一行神奇的js代码,当时我就震惊了,这不就是传说中的ZB神奇么… … 哈哈。写本篇文章的缘由是之前看到了一段js代码,如下:

然后让大家运行,出来的结果让人有点出乎意料,“sb”。太风骚了有木有!如果有人诋毁前端瞧不起js的话,那就可以把这段代码发给他了~不过话说回来了,这到底是什么原理呢?为什么一堆符号运算结果竟然能是两个字符,而且恰巧还是个sb!

其实靠的是js的类型转化的一些基本原理,本篇就来揭密”sb”是如何炼成的。相信你如果能把这个理清楚了,以后遇到类型转化之类的题目,就可以瞬间秒杀了。

一、js运算符的优先级

首先要运用到的第一个知识就是js运算符的优先级,因为这么长一段运算看的人眼花,我们必须得先根据优先级分成n小段,然后再各个击破。优先级的排列如下表,优先级从高到低:


本人在职前端开发,如果你也想学习前端开发技术,可以加入我组建的前端学习交流裙:851 231 348 也可以关注
我的微信公众号:【前端留学生】自己根据多年来的开发经验总结录制的一套web前端精讲视频和学习方法,
以及一些前端学习手册,前端面试题,端开发工具,PDF文档书籍教程,无偿分享给大家。需要的话都可以自行来获取下载。

根据此规则,我们把这一串运算分为以下16个子表达式:
运算符用红色标出,有一点可能大家会意识不到,其实中括号[]也是一个运算符,用来通过索引访问数组项,另外也可以访问字符串的子字符,有点类似charAt方法,如:’abcd’[1] // 返回’b’。而且中括号的优先级还是最高的哦。

二、js的类型转化

预处理结束,接下来需要运用的就是JavaScript的类型转化知识了。我们先说说什么情况下需要进行类型转化。

当操作符两边的操作数类型不一致或者不是基本类型(也叫原始类型)时,需要进行类型转化。先按运算符来分一下类:

减号-,乘号*,肯定是进行数学运算,所以操作数需转化为number类型。

加号+,可能是字符串拼接,也可能是数学运算,所以可能会转化为number或string

一元运算,如+[],只有一个操作数的,转化为number类型

下面来看一下转化规则。

1、 对于非原始类型的,通过ToPrimitive() 将值转换成原始类型:

ToPrimitive(input, PreferredType?)

可选参数PreferredType是Number或者是String。返回值为任何原始值。如果PreferredType是Number,执行顺序如下:

如果input为primitive,返回

否则,input为Object。调用 obj.valueOf()。如果结果是primitive,返回。

否则,调用obj.toString(). 如果结果是primitive,返回

否则,抛出TypeError

如果 PreferredType是String,步骤2跟3互换,如果PreferredType没有,Date实例被设置成String,其他都是Number。

2、 通过ToNumber()把值转换成Number,直接看ECMA 9.3的表格

规则如下:

3. 通过ToString()把值转化成字符串, 直接看ECMA 9.8的表格

规则如下:
规则就这么多,接下来实践一下,根据我们上面划分出的子表达式,一步一步将这个神奇的代码给执行出来。开工~

三、步步执行

先看最简单的子表达式16:+[]

只有一个操作数[],肯定是转化为number了,根据上面的规则2,[]是个数组,object类型,即对象。所以得先调用toPrimitive转化为原始类型,并且PreferredType为number,这个参数表示更“倾向于”转化的类型,这里肯定是number了。然后首先调用数组的valueOf方法,数组调用valueOf会返回自身,如下:
这个时候,我们得到一个空串“”,还没有结束,看上面的规则2描述,继续调用toNumber,转化为number类型,如下:
大功告成!子表达式16转化完毕,+[],最终得到0。来看子表达式15:[~+””]

空串””前面有两个一元操作符,但是操作数还是只有一个,所以,最终要转化为的类型是number。看规则2吧,空串调用toNumber得到0。

接下来是,这是个什么东东呢?它是位运算符,作用可以记为把数字取负然后减一,所以0就是-1 。

别忘了,这个子表达式外头还包着中括号,所以最终的值为[-1],即一个数组,里面只有一个元素-1。

接下来看子表达式13就简单了,把15、16求出来的填进去,就变成了这样:–[-1][0],取数组的第0个元素,然后自减,结果为-2,是不so easy!

继续往上走,子表达式14:[~+[]]

其实把15、和16的原理用上就非常明显了,答案[-1]

继续来求子表达式9,此刻它已变成:-2*[-1],有稍许不一样,不过没关系,我们还是按照规则来,运算符是乘号*,当然是做数学运算,那后面的[-1]就得转化为number,与16的求法类似,过程如下:

1)、调用toPrimitive,发现是object类型

2)、调用valueOf,返回自身[-1]

3)、因为不是原始类型,继续调用toString,返回”-1″

4)、”-1″是原始类型了,然后调用toNumber,返回-1

5)、与-2相乘,返回2

子表达式10:~~!+[],不多说了,答案1. 就是从右往左依次一元计算。

有了9和10,我们来到了子表达式4,此刻它已经长这样了:2+1, 好,我不多说了。

继续看表达式7:!(+[]),+[]=-1,这个根据上面已经知道了,那!-1是什么呢?这里要说一下这个感叹号,它是逻辑取非的意思,会把表达式转化为布尔类型,转化规则和js的Truthy和Falsy原则是一样的,后面跟数字的,除0以外都为false,后面跟字符串的,除空串以外都为false。

这里的!-1当然就是false了。

接下来这个表达式3:false+{}有点关键。一个布尔加一个对象,那这个{}应该先转化为原始类型,流程如下:

1)、调用toPrimitive,发现是object类型

2)、调用valueOf,返回自身{},

3)、不是原始类型,调用toString,返回”[object Object]”

4)、false与”[object Object]”相加,false先转化为字符串”false”

5)、相加得结果”false[object Object]”

知道了表达式3和4,我们就可以来看表达式1了,此时它是这样的:”false[object Object]”[3],因为这个[]可以取字符串的子字符,像charAt一样,所以得到了结果”s”

四、最后

经过上面艰难的流程,我们拿到了字符”s”,也就是那张图的左半边,剩下的那个”b”,相同的原理可以搞出来,我这里就不一一演示了,留给你练练吧。

回顾一下这个过程其实也不复杂,只是有一些需要重复劳动的,只要你掌握了运算的优先级,能把大串分解成一个个小串,然后运用类型转化的知识挨个处理就搞定了。

怎么样,看到这里你还觉得神奇吗?

如果有人瞧不起js,请把这段代码发给他,如果他想知道答案,请把本文发给他~

一行能装逼的JavaScript代码,就是怎么sao相关推荐

  1. 一行能装逼的JavaScript代码的延伸

    前段就是坑,入坑水真深. 先看看一个黑科技, 纳尼,这是什么东西. (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+ ...

  2. 一行能装逼的 JavaScript 代码

    点击上方"逆锋起笔",公众号回复 PDF 领取大佬们推荐的学习资料 一行神奇的js代码,当时我就震惊了,这不就是传说中的ZB神奇么- - 哈哈.写本篇文章的缘由是之前看到了一段js ...

  3. 一行能装逼的JavaScript代码

    点击上方"蓝色字体",选择"设为星标" 做积极向上的前端人! 作者:xixi 链接:https://www.cnblogs.com/telnetzhang/p/ ...

  4. Java8之写一个装逼的函数式代码

    Java8之将普通方法写一个装逼的函数式代码 首先看代码 下面的方法很简单就是从数据中找一个值,找到返回. @Testpublic void test2() {Integer [] c = new I ...

  5. 如何读懂并写出装逼的函数式代码

    今天在微博上看到了 有人分享了下面的这段函数式代码,我把代码贴到下面,不过我对原来的代码略有改动,对于函数式的版本,咋一看,的确令人非常费解,仔细看一下,你可能就晕掉了,似乎完全就是天书,看上去非常装 ...

  6. 如何读懂并写出装逼的函数式代码 1

    今天在微博上看到了 有人分享了下面的这段函数式代码,我把代码贴到下面,不过我对原来的代码略有改动,对于函数式的版本,咋一看,的确令人非常费解,仔细看一下,你可能就晕掉了,似乎完全就是天书,看上去非常装 ...

  7. 代码 抠图_Python装逼指南——五行代码实现批量抠图!

    你是否曾经想将某张照片中的人物抠出来,然后拼接到其他图片上去,从而可以即使你在天涯海角,我也可以到此一游?专业点的人使用 PhotoShop 的"魔棒"工具可以抠图,非专业人士可以 ...

  8. Python装逼指南——五行代码实现批量抠图!

    你是否曾经想将某张照片中的人物抠出来,然后拼接到其他图片上去,从而可以即使你在天涯海角,我也可以到此一游?专业点的人使用 PhotoShop 的"魔棒"工具可以抠图,非专业人士可以 ...

  9. Python装逼指南——五行代码实现批量抠图

    你是否曾经想将某张照片中的人物抠出来,然后拼接到其他图片上去,从而可以即使你在天涯海角,我也可以到此一游? 专业点的人使用 PhotoShop 的"魔棒"工具可以抠图,非专业人士可 ...

最新文章

  1. 网站搭建从零开始(六) WordPress的基本配置
  2. java 正则表达式 提取ip_java正则表达式提取地址中的ip和端口号
  3. 关于perl和shell的参数传递
  4. Spring和JSF集成:异常处理
  5. Mysql按时间段分组查询来统计会员的个数
  6. 11款超5000星 后台管理模板, 总有一款适合你!
  7. msgbox php,HTML_MsgBox函数语言参考,描述  在对话框中显示消息 - phpStudy
  8. 协方差矩阵与PCA原理深入剖析
  9. 基于ESP8266的人体红外感应报警系统设计
  10. vmware安装winxp
  11. NCBI:美国国立生物技术信息中心大型数据库
  12. Keil5_C51安装
  13. django学习问题及解决方法
  14. 用递归算法实现赶鸭子问题和角谷定理
  15. 一篇文章说清楚TensorFlow是什么
  16. IE11升级(不联网模式)之P处理
  17. Flash(Flex)对文件下载进度的监控原理分析
  18. js处理本地.bin音频文件和node.js的fs模块处理本地.bin音频区别
  19. cesium有地球与无地球模式切换
  20. AI 算法工程师 必备技能 知识图谱

热门文章

  1. 制度化规范化标准化精细化_管理技巧:为什么说企业制度化管理势在必行?好处太多了...
  2. android优美列表页面,android listview 列表 点击列表进入详细页面
  3. php继承exten,es6,extends_react中通过extend继承,父组件为什么能访问子组件的属性,es6,extends,react.js - phpStudy...
  4. django mysql 2059_Django mysqlclient后端生成django.db.utils。操作错误:(2059,NULL)在Windows中...
  5. 12c跨平台完成PDB的备份迁移
  6. 如何利用 AVFoundation 设计一个通用稳定的音视频框架?
  7. web服务端的架构演变
  8. Opencv笔记(十八)——轮廓的更多函数及其层次结构
  9. 如何展开Linux Memory Management学习?
  10. 阅读verilog程序总结