(![] + [])[+ []]…解释为何有效


107
alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]);

该代码的输出为:fail。为什么?

顺便说一句(![]+[])[+!+[]] == 'false'[1],对吗?但是为什么![]+[] == "false"和为什么+!+[] == 1呢?


14
@Snoob我不相信你。最后,这是一个叉子炸弹。
Johannes Schaub-litb

3
当然,这是字符串文字;)
Yi Jiang

3
(![]+[])[+[]]是“F”(第一个从“假”炭),(![]+[])[+!+[]]是“A”,等等
毛雅伯

3
@Snoob:正如您所说,您可以在浏览器上测试每个表达式。alert(![]+[])然后尝试alert(+!+[]),您会看到的。
Mauricio Scheffer

12
不管是否有用,我发现这是一个有趣的问题,并且希望看到措辞充分的解释。如果考虑实用性或实用性,许多Code Golf都将关闭。练习和游戏本身对扩大思维和思考过程很有用。
约翰·K

Answers:


127

正如@Mauricio所评论的(![]+[])[+[]]是“ f”(“ false”的第一个字符),(![]+[])[+!+[]])“ a”等,等等。

它是如何工作的?

让我们检查第一个字符“ f”:

(![]+[])[+[]]; // 'f'

表达式的第一部分(括号之间)由组成![]+[],加法运算符的第一个操作数是![],它将产生false,因为数组对象(与任何其他Object实例一样)是真实的,并且应用Logical(!)NOT一元运算符,false例如,它产生值。

![]; // false, it was truthy
!{}; // false, it was truthy
!0;  // true, it was falsey
!NaN;  // true, it was falsey

在它之后,我们有加法运算符的第二个操作数,即空数组,[]仅用于将false值转换为字符串,因为空数组的字符串表示形式只是一个空字符串,它等效于:

false+[]; // "false"
false+''; // "false"

最后一部分,括号后面的一对方括号,它们是属性访问器,它们接收一个表达式,该表达式由再次应用于空数组的Unary Plus运算符组成。

一元加运算符的作用是将类型转换为Number,例如:

typeof +"20"; // "number"

再一次,这将应用于空数组,就像我之前说的,数组的String表示是一个空字符串,当您将一个空字符串转换为Number时,它会转换为零:

+[]; // 0, because
+[].toString(); // 0, because
+""; // 0

因此,我们可以通过以下步骤将表达式“解码”为:

(![]+[])[+[]];
(false+[])[+[]];
(false+'')[+[]];
(false+'')[0];
('false')[0];  // "f"

请注意,通过在字符串值上使用方括号符号访问字符不是ECMAScript 3rd的一部分。版本规范(这就是该charAt方法存在的原因)。

但是,这种表示字符串字符的“索引属性”已在ECMAScript 5上进行了标准化,甚至在标准化之前,该功能就已经在许多浏览器中使用(甚至在IE8(标准模式)下)。


46
只是希望这绝不是面试问题。
Inisheer

4
@JTA:希望!我会过去的:-D
毛里西奥·谢弗

18
“ i”来自哪里?
Josh Stodola,2010年

5
@rlemon,int语言上没有数据类型,实际上所有数字都是双精度64位格式(IEEE 754值),即使某些运算符在内部使用整数值(如按位运算符),结果始终是双精度。该'i'进来从这个例子undefined,但它可能来自Infinity例如:(+!+[]/+[+[]]+[])[!+[]+!+[]+!+[]]=> (1/0+'')[3]=> (Infinity+'')[3]=>'i'
CMS

5
@JoshStodola好吧,大约3个月后,进一步澄清。在这种情况下,“ i”来自“未定义”,是的,但是这里涉及另一个技巧。所述的代码连接“假”到“未定义”到形式"falseundefined":(使用构建[![]]+[][[]]在其中的索引“i”是10)+!+[]+[+[]]给出"10"。这用于提取“ i”(如果可以将字符串索引显然强制为整数,则可以在javascript中使用字符串索引)。产生它的最终构造是:([![]]+[][[]])[+!+[]+[+[]]]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.