(![] + [])[+ []] ...解释为什么这会起作用

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

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

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


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

它是如何工作的?

我们来看看第一个字符'f':

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

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

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

在它之后,我们添加了第二个操作数,一个空的Array, [] ,这是为了将false值转换为String,因为空数组的字符串表示形式只是一个空字符串,相当于:

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

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

例如,Unary Plus Operator所做的是将类型转换为Number

typeof +"20"; // "number"

再次,这是应用于一个空的数组,并且正如我之前所说,数组的字符串表示形式是一个空字符串,并且当您将空字符串转换为数字时,它将转换为零:

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

因此,我们可以在一些步骤中“解码”表达式:

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

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

然而,这种代表字符串字符的“索引属性”在ECMAScript 5中是标准化的,甚至在标准化之前,该功能在许多浏览器(甚至在IE8(标准模式))中都可用。

链接地址: http://www.djcxy.com/p/8417.html

上一篇: (![]+[])[+[]]... Explain why this works

下一篇: May an OAuth 2.0 access token be a JWT?