(澳门网上娱乐平台) 谁来解释一下这串神奇的Javascript代码?

上代码:

!~+[]+{}[--[~+""][+[]]*[~+[]] + ~~!+[]]+{}+[][[~!+[]]*~+[]]

可在任何 Javascript 环境中使用。输出方法:

console.log !~+[]+{}[--[~+""][+[]]*[~+[]] + ~~!+[]]+{}+[][[~!+[]]*~+[]]
;

刚自己在node下一句一句调了看下,其实就是各种类型的隐式转换:
我们先把上面的代码拆分为两个部分:
!~+[] + {}[--[~+""][+[]] * [~+[]] + ~~! +[]]{} + [][[~!+[]] * ~+[]]

对于前面的一串代码!~+[] + {}[--[~+""][+[]] * [~+[]] + ~~! +[]]
+[]在方括号申明的空数组前面加+号,将 Array 类型隐式转换为了 Number 类型,空数组对应的 Number 就是 0。
~+[]在 0 前面加上 ~ 号,表示按位取反,参考这里Javascript 按位取反运算符 ~,得到的结果就应该是 -1。
!~+[]在 -1 前加 ! 号是隐式转换为 Boolean 型。-1 对应的布尔类型当然就是 false。
!~+[] + {}这个考察的就是,在 + 运算符的前后两个运算元都不为 Number 或 String 类型时,将自动调用两个运算元的 toString 方法,同时转换为 String 类型进行拼接。所以此处输出 false[object Undefined] // 注意,这里是字符串

!~+[] + {}[/* index */]这里便是在对之前的字符串进行取值,因为我们知道 JS 中的 String 是可以通过类似数组的方法获得某个字符的。例如var str = "Hello World"; var char = str[4]; // 数组下标以 0 开始。那我们接下来就看看,它到底要取哪个字符。

--[~+""][+[]] * [~+[]] + ~~! +[]左边代码最终的值便是它要取的 index。那我们开始分析这段值是多少:
--[~+""][+[]]按照之前的方法,从最里面开始分析,一个 “” 表示空字符串,前面加上 + 号,是隐式转换为 Number 类型,此处转换后的值为 0,接着前面遇到一个 ~ 符号,之前有介绍,这是按位取反符号,按位取反后中括号中的~+""值为 -1,紧接着,[-1]则表示一个索引数组,其中有一个元素,它的值为 -1。然后[-1][+[]],根据上面的经验我们知道,这段代码等价于 [-1][0],所以它最终取得该数组的第一个元素,也就是 -1。最后,-- -1这个
运算,表示在进行后面运算之前,对当前值做自减 1,所以当前代码块 结果为 -2。

换个行,缓一下。

--[~+""][+[]] * [~+[]]此处,在后面乘了一个 [~+[]] 由上面,我们可以知道,这是乘了一个 [-1],那乘以一个数组该怎么搞呢,在这里,也是将其进行隐式转换,刚好此数组只有一个元素,那转换为 Number 便是取其第一个元素转换为 Number 类型。这小段代码最终的值便是 2。
在这段代码后面,还加上了这么一段~~!+[],还是根据上面的分析方法,+[]的值为 0, ! 为强制转换为 Boolean 类型,0 转换为布尔类型便是 false, ~ 为按位取反,对于一个数字来说,两次按位取反就等于它本身。 这里 ~将 Boolean 类型强制转换为 Number 类型, false 对应的 Number 类型值为 0,所以 ~~!0的结果为 1 。

将上面的结果做以整理可以知道,--[~+""][+[]] * [~+[]] + ~~! +[]的值为 3 。最终是取false[object Undefined] // 此处为字符串的第三位字符,既为 s。(写这么多就是为了取一个 s 。。。)

后面同样的分析方法,{}+[]则是将对象和数组转换为 String 类型进行相加, 空数组转换为 String 后为空字符串,所以上面的代码转换后值为 [object Object] // 此处为字符串
后面的代码则是获得此字符串的某个字符。[~!+[]] * ~+[],这一串代码的执行结果,则为需要获得的字符的下标值。[~!+[]] 的运算值为 [-2] // 是一个数组,这个数组再乘以 ~+[]运算结果为 -1,则将两个运算元隐式转换为 Number 类型,相乘结果为 2。

最终,后半句代码是获得[object Object] // 此处为字符串这个字符串的第二位字符 b。

最终输出啥,估计都知道了吧。个人感觉,这段神奇的代码是一个很好的关于 javascript 隐式类型转换的知识的例子。这也绕。。。

发表评论

电子邮件地址不会被公开。 必填项已用*标注