(![]+[])[+[]]… Explain why this works
1
| alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]); |
此代码的输出为:fail。为什么?
顺便问一下,(![]+[])[+!+[]] == 'false'[1]对吗?但是为什么是![]+[] =="false",为什么是+!+[] == 1?
- @我不相信你。最后,它是一个叉形炸弹。
- :这只是一个JS代码,我不能伤害你。
- 当然,它是一个字符串文本;)
- (![]+[])[+[]]为"f"(来自"false"的第一个字符),(![]+[])[+!+[]]为"a"等。
- 您应该将标题改为"解释为什么这项工作"而不是"这是什么?"-答案很明显。如果用更恰当的措辞,人们就不太可能结束这个问题。
- 为什么?[]+[])+!+[]是"A"
- 我认为谁写的这段代码真的是一个大师级的javascript代码编写者:d//需要重新打开这个问题
- @正如你所说,你可以在浏览器上测试每个表达式。先试试alert(![]+[]),然后再试试alert(+!+[]),你会看到的。
- 顺便说一句,这对于一个模糊的比赛是很可爱的,但在其他方面是没用的。
- @毛里西奥·谢弗:(![]+[])+!+[]='假'[0]对吗?但是为什么呢![]+[]='假',为什么是+!+[]=0?
- @snoob类型的coersion-+将空数组转换为数字。在[]前面的!将其转换为布尔值,依此类推。
- 不管有用与否,我觉得这是一个有趣的问题,我希望看到一个措辞恰当的解释。如果考虑到实用性或实用性,许多代码GOLF将被关闭。练习和游戏本身有助于拓展思维和思考过程。
- @snoob:它使用+把东西转换成int,用!把东西转换成boolean。
- 好问题,还有更多的问题吗?
- patriciopalladino.com/blog/2012/08/09/…
正如@mauricio所评论的,(![]+[])[+[]]是"f"(第一个字符是"false"),(![]+[])[+!+[]])是"a"等…
它是如何工作的?
让我们检查第一个字符"f":
括号之间表达式的第一部分由![]+[]组成,加法运算符的第一个操作数是![],它将生成false,因为数组对象与任何其他对象实例一样是真实的,并且应用逻辑的(!)不是一元运算符,它生成值false。
1 2 3 4
| ![]; // false, it was truthy
!{}; // false, it was truthy
!0; // true, it was falsey
!NaN; // true, it was falsey |
在它之后,我们得到加法的第二个操作数,一个空数组,[],这是为了将false值转换为字符串,因为空数组的字符串表示形式只是一个空字符串,相当于:
1 2
| false+[]; //"false"
false+''; //"false" |
最后一部分是括号后的一对方括号,它们是属性访问器,它们接收一个表达式,该表达式由再次应用于空数组的一元加号运算符构成。
一元加号运算符所做的是类型转换,到Number,例如:
1
| typeof +"20"; //"number" |
再一次,这应用于空数组,正如我前面所说,数组的字符串表示形式是空字符串,当您将空字符串转换为数字时,它将转换为零:
1 2 3
| +[]; // 0, because
+[].toString(); // 0, because
+""; // 0 |
因此,我们可以通过以下步骤"解码"表达式:
1 2 3 4 5
| (![]+[])[+[]];
(false+[])[+[]];
(false+'')[+[]];
(false+'')[0];
('false')[0]; //"f" |
注意,在字符串值上使用括号表示法访问字符并不是ECMAScript第三版规范的一部分(这就是存在charAt方法的原因)。
然而,这种表示字符串字符的"索引属性"在ECMAScript 5上进行了标准化,甚至在标准化之前,该功能在许多浏览器(甚至在IE8(标准模式))中都可用。
- 希望这不是面试问题。
- @JTA:希望如此!我本可以通过的。
- !+[]->为什么是真的?
- "我"是从哪里来的?
- "欠罚款":D
- @snoob,因为+[]产生零,0不真实,因此在布尔上下文中,它将产生false,逻辑非运算符将其否定:!+[]=>!0=>!false=>true。
- @rlemon语言中没有int数据类型,事实上,所有数字都是双精度64位格式(ieee 754值),尽管有些运算符内部使用整数值(如位运算符),但结果始终是双精度的。'i'在本例中来自undefined,但它可以来自Infinity,例如:(+!+[]/+[+[]]+[])[!+[]+!+[]+!+[]]=>(1/0+'')[3]=>(Infinity+'')[3]=>'i'。
- @约什斯托多拉,3个月后,进一步澄清。本例中的"i"来自"undefined",是的,但这里涉及到另一个技巧。代码将"false"与"undefined"连接起来,形成"falseundefined"(使用:[![]]+[][[]]构造),其中"i"的索引为10。+!+[]+[+[]]给"10"。这用于提取"i"(如果字符串索引可以明显地强制为整数,则可以在javascript中使用)。最终的构造是:([![]]+[][[]])[+!+[]+[+[]]]。