javascript - 为什么++[[]][+[]]+[+[]] 返回字符串 "10"?

标签 javascript syntax

这是有效的,并在 JavaScript 中返回字符串 "10" (more examples here):

console.log(++[[]][+[]]+[+[]])

为什么?这里发生了什么?

最佳答案

如果我们将其拆分,则困惑等于:

++[[]][+[]]
+
[+[]]

在 JavaScript 中,+[] === 0 为真。 + 将某些内容转换为数字,在这种情况下,它将归结为 +""0(请参阅下面的规范详细信息)。

因此,我们可以简化它(++优先于+):

++[[]][0]
+
[0]

因为 [[]][0] 的意思是:从 [[]] 中获取第一个元素,所以:

[[]][0] 返回内部数组 ([])。由于引用,说 [[]][0] === [] 是错误的,但让我们调用内部数组 A 以避免错误的表示法。

++ 在其操作数之前表示“加一并返回递增的结果”。所以 ++[[]][0] 等同于 Number(A) + 1(或 +A + 1)。

同样,我们可以将困惑简化为更清晰的内容。让我们用 [] 代替 A:

(+[] + 1)
+
[0]

+[]可以将数组强制转换为数字0之前,需要先强制转换为字符串,即"" >,再次。最后,添加 1,结果为 1

  • (+[] + 1) === (+""+ 1)
  • (+""+ 1) === (0 + 1)
  • (0 + 1) === 1

让我们进一步简化它:

1
+
[0]

此外,在 JavaScript 中也是如此:[0] == "0",因为它是用一个元素连接一个数组。连接将连接由 , 分隔的元素。对于一个元素,您可以推断出此逻辑将导致第一个元素本身。

在这种情况下,+ 看到两个操作数:一个数字和一个数组。它现在试图将两者强制为同一类型。首先,数组被强制转换为字符串 "0",接下来,数字被强制转换为字符串 ("1")。 数字 + 字符串 === 字符串

"1" + "0" === "10" // Yay!

+[] 的规范详细信息:

这是一个迷宫,但是要执行 +[],首先要将其转换为字符串,因为这就是 + 所说的:

11.4.6 Unary + Operator

The unary + operator converts its operand to Number type.

The production UnaryExpression : + UnaryExpression is evaluated as follows:

  1. Let expr be the result of evaluating UnaryExpression.

  2. Return ToNumber(GetValue(expr)).

ToNumber() 说:

Object

Apply the following steps:

  1. Let primValue be ToPrimitive(input argument, hint String).

  2. Return ToString(primValue).

ToPrimitive() 说:

Object

Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

[[DefaultValue]] 说:

8.12.8 [[DefaultValue]] (hint)

When the [[DefaultValue]] internal method of O is called with hint String, the following steps are taken:

  1. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString".

  2. If IsCallable(toString) is true then,

a. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.

b. If str is a primitive value, return str.

数组的 .toString 说:

15.4.4.2 Array.prototype.toString ( )

When the toString method is called, the following steps are taken:

  1. Let array be the result of calling ToObject on the this value.

  2. Let func be the result of calling the [[Get]] internal method of array with argument "join".

  3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).

  4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.

所以 +[] 归结为 +"",因为 [].join() === ""

同样,+ 定义为:

11.4.6 Unary + Operator

The unary + operator converts its operand to Number type.

The production UnaryExpression : + UnaryExpression is evaluated as follows:

  1. Let expr be the result of evaluating UnaryExpression.

  2. Return ToNumber(GetValue(expr)).

ToNumber"" 定义为:

The MV of StringNumericLiteral ::: [empty] is 0.

因此 +""=== 0,因此 +[] === 0

关于javascript - 为什么++[[]][+[]]+[+[]] 返回字符串 "10"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30779807/

相关文章:

将 PHP 转换为 JS 的 PHP 代码

C中变量名后的冒号

javascript - 在多个元素上切换类 react

javascript - 严格值比较(小于/大于)

jquery - 如何格式化 Ben Alman 的 jQuery Debounce

Objective-C block 语法

javascript - 在页面末尾加载 JavaScript。为什么?

javascript - 使用 Emscripten 将 R 函数编译为 JavaScript

javascript - 使用 setInterval 循环从网页上的 JavaScript 发布到 Node 端点

javascript - 如何用appendChild添加多个div?