0

我正在阅读这些幻灯片,发现以下 javascript 行:

 ({} + [])[!![] + !![] + !![]] + (![] + [])[!![] + !![] + !![]]

如果您在控制台执行此行,它将返回“js”。 更改代码会使该行返回不同的字母。我几乎可以返回我的名字(缺少“n”):

({} + [])[!![] + !![] + !![]] + (![] + {})[!![] + !![] + !![] + !![]] + (![] + {})[![] + !![] ]

为什么会发生这种情况?这是如何工作的?幻灯片没有提供太多关于它的信息。

4

2 回答 2

2
  • {} + []:当+有除数字以外的操作数时,它调用toString两个操作数并连接它们的值。{}.toString()返回[object Object][].toString()返回数组的内容,它只是一个空字符串,因为数组不包含任何内容:

     ("[object Object]" + "")[!![] + !![] + !![]] + (![] + [])[!![] + !![] + !![]]
    
     ==>
    
     "[object Object]"[!![] + !![] + !![]] + (![] + [])[!![] + !![] + !![]]
    
  • []转换为布尔值时,它返回 true。!!如果其操作数不与undefinednull0或空字符串比较,则逻辑返回 true ""。因此!![]返回真。

    当对布尔值进行算术运算时,会执行整数提升。值truefalse分别转换为10

    "[object Object]"[true + true + true] + (![] + [])[true + true + true]
    
    ==>
    
    "[object Object]"[1 + 1 + 1] + (![] + [])[1 + 1 + 1]
    
    ==>
    
    "[object Object]"[3] + (![] + [])[3]
    
  • 下标运算符[n]获取(n + 1)-th类数组结构的成员(因为数组是 0 索引的)。第一个[3]获取字符串的第 4 个字符,其为"j"

    "j" + (![] + [])[3]
    
  • ![]返回 false (因为[]是真实的)并[]返回一个空字符串:

    "j" + (false + "")[3]
    
    ==>
    
    "j" + "false"[3]
    
  • 中的第 4 个字符"false"是“s”(数组索引为 0)。所以这解决了:

    "j" + "s"
    
    ==> "js"
    
于 2013-04-02T12:52:46.587 回答
1

如果你仔细观察,有两件事情发生,一件是添加一个空对象和一个数组,另一件是索引器。

在 JS 中,{} + []返回 0

({} + [])返回“[对象对象]”

[] + {}返回“[对象对象]”

![] + {}返回“假[对象对象]”

(![] + [])返回“假”

此外,由于一切都是类型可转换的,所以true+true= 2(true 等价于 1)。 !![]将返回true(布尔值),因此!![] + !![] + ![]true + true + true等于 3 的操作相同。

因此,为此,您正在评估以字符串形式出现的内容,然后对这些字符串进行索引以获取各个字符。您可以从“假”和“对象”这两个词中进行选择。

于 2013-04-02T12:49:48.300 回答