(![]+[])[+[]]... Explain why this works

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

The output of this code is: fail. Why?

15025 次浏览

由于@Mauricio 注释 (![]+[])[+[]]是“ f”(“ false”的第一个字符) ,(![]+[])[+!+[]])是“ a”,等等... ..。

它是怎么工作的?

让我们来看看第一个字符‘ f’:

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

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

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

After it, we have the second operand of the addition, an empty Array, [], this is made just to convert the false value to String, because the string representation of an empty array is just an empty string, is equivalent to:

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

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

Unary Plus 运算符所做的是类型转换,例如,到 Number:

typeof +"20"; // "number"

One more time, this is applied to an empty Array, and as I said before, the String representation of an Array is an empty string, and when you convert an empty string to Number, it is converted to zero:

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

因此,我们可以通过一些步骤对这个表达式进行“解码”:

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

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

然而,这种表示字符串字符的“索引属性”在 ECMAScript 5中是标准化的,甚至在标准化之前,这个特性就已经在很多浏览器中可用(甚至在 IE8(标准模式)中)。