为什么以及如何 ([![]]+[][[]])[+!+[]+[+[]]] 计算为字母“i"? [英] Why and how does ([![]]+[][[]])[+!+[]+[+[]]] evaluate to the letter "i"?

查看:19
本文介绍了为什么以及如何 ([![]]+[][[]])[+!+[]+[+[]]] 计算为字母“i"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读 这篇发表在 dzone 上的文章 时,我发现了一段 JavaScript 最初由 Marcus Lagergren 在 Twitter 上发布.

While reading this article posted on dzone I found a snippet of JavaScript originally posted on Twitter by Marcus Lagergren.

以下代码显然打印了字符串 "fail"

The following code apparently prints the string "fail"

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

这涉及隐式类型转换,我正在尝试了解如何准确解释这一行.

This involves implicit type casting and I'm trying to understand how exactly this line is interpreted.

我已经隔离了每个角色

  • (![]+[])[+[]] 打印 "f"
  • (![]+[])[+!+[]] 打印 "a"
  • ([![]]+[][[]])[+!+[]+[+[]]] 打印 "i"
  • (![]+[])[!+[]+!+[]] 打印 "l"
  • (![]+[])[+[]] prints "f"
  • (![]+[])[+!+[]] prints "a"
  • ([![]]+[][[]])[+!+[]+[+[]]] prints "i"
  • (![]+[])[!+[]+!+[]] prints "l"

除了 "i"

![] 空数组是一个对象,根据 ECMAScript 文档,点 9.2 在转换为 boolean 时评估为 true 所以这是 false

![] an empty array is an Object, which according to ECMAScript documentation, point 9.2 evaluates to true when converted to a boolean so this is false

false+[] 根据 第 11.6.1 点 二进制 + 运算符的两个参数都被转换为 String,因此我们得到 "false"+"",它计算 "false"代码>

false+[] as per Point 11.6.1 both arguments of the binary + operator get converted to String, therefore we get "false"+"", which evaluates "false"

+[] 如果参数是 Object<,一元加运算符会导致 ToNumber 转换,然后是 ToPrimitive 转换/代码>.这种转换的结果是通过调用对象的[[DefaultValue]] 内部方法来确定的.如果是空数组,则默认为 0.(ECMAScript 文档,部分:11.4.69.39.1 )

+[] a unary plus operator causes a ToNumber conversion followed by a ToPrimitive conversion if the argument is an Object. The result of such conversion is determined by calling the [[DefaultValue]] internal method of the object. In case of an empty array, it defaults to 0. (ECMAScript Documentation, sections: 11.4.6, 9.3, 9.1 )

"false"[0] 我们正在访问索引 0 处的字符,因此 "f"

"false"[0] we're accessing the character at index 0, hence the "f"

同样的故事,这里唯一的区别是方括号中的部分中的额外转换(计算结果为一个数字以指向字符串 "false" 中的另一个字符),由使用触发一元 +! 运算符.

Same story, the only difference here are additional conversions in the part in square brackets (which evaluates to a number to point at another character in the string "false"), triggered by the use of unary + and ! operators.

+[] 计算结果为 0,如上所述.

+[] evaluates to 0, as explained above.

!0 计算结果为 true,如 第 9.2 节第 11.4.9 节.首先,0 被转换为布尔值 false,然后运算符将值取反.

!0 evaluates to true as defined in Section 9.2 and Section 11.4.9. First, 0 is converted to a boolean false and then the operator inverts the value.

+true 再次,一元加号触发一个 ToNumber 转换,它返回一个 1 二进制 true(第 11.4.6 节9.3)

+true again, the unary plus triggers a ToNumber conversion, which returns a 1 for binary true (Section 11.4.6 and 9.3)

"false"[1] 返回字符串中的第二个字符,即 "a"

"false"[1] returns the second character in the string, which is "a"

!+[] 计算结果为 true,如上所述

!+[] evaluates to true as explained above

true+true 在原语上使用二进制 + 会触发 ToNumber 转换.如果为真,其结果为 1 并且 1+1 等于 2

true+true using the binary + on primitives triggers a ToNumber conversion. In case of true, its result is 1 and 1+1 equals 2

"false"[2] - 不言自明

让我难受的是字母 "i".我可以看到第二部分(在方括号中)计算结果为字符串 "10" 并且第一部分(在括号中)返回 "falseundefined"我无法理解这是如何发生的.有人能一步一步解释一下吗?尤其是方括号的神奇之处?(数组和数组访问)

What leaves me stumped is the letter "i". I can see that the second part (in square brackets) evaluates to the string "10" and that the first part (in parentheses) returns "falseundefined" but I can't make heads or tails of how this is happening. Could someone explain it step by step? Especially the magic that happens with square brackets? (arrays and array access)

如果可能,我希望每个步骤都包含一个指向底层 ECMAScript 规则的链接.

我觉得最神秘的是这部分:[][[]]

What I find the most cryptic is this part: [][[]]

推荐答案

如果你稍微重写一下,你的神秘部分就不是那么神秘了:

Your cryptic part isn't all that cryptic if you rewrite it a little:

[]['']

[] 将被强制转换为字符串,因为它不是整数,因此您正在寻找名为 [] 属性''(空字符串).您只会得到 undefined,因为没有具有该名称的属性.

[] will be coerced into a string because it isn't an integer, so you're looking for a property of [] with the name '' (an empty string). You'll just get undefined, as there is no property with that name.

至于实际的字母,将表达式分为两个主要部分:

As for the actual letter, break the expression up into the two main components:

  • 字符串([![]]+[][[]]):
    • [![]][false].
    • [][[]]未定义.
    • 将它们加在一起得到 "falseundefined".
    • [+[]][0].
    • +[][] 强制转换为整数,所以你得到 0.
    • !+[]0 强制转换为布尔值并将其取反,因此您得到 true.
    • +!+[]true 强制转换为整数,因此您得到 1.
    • 把它们加在一起,你得到 ["10"].
    • [+[]] is [0].
    • +[] coerces [] to an integer, so you get 0.
    • !+[] coerces 0 to a boolean and negates it, so you get true.
    • +!+[] coerces true to an integer, so you get 1.
    • Add them together, and you get ["10"].

    当使用字符串访问数组的属性并且该字符串恰好是数组的一个元素时,该字符串被强制转换为整数并返回数组的实际元素:

    When using a string to access the properties of the array and the string happens to be an element of the array, the string is coerced into an integer and you get back the actual element of the array:

    > [1, 2, 3]["0"]
    1
    > [1, 2, 3]["1"]
    2
    

    所以你的最终结果是:

    > "falseundefined"["10"]
    "i"
    

    阅读这个答案,了解对[false] + undefined 部分的解释.

    Read this answer for an explanation of the [false] + undefined part.

    这篇关于为什么以及如何 ([![]]+[][[]])[+!+[]+[+[]]] 计算为字母“i"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆