Why does the JavaScript expression ++[[]][+[]]+[+[]] evaluate to the string “10”? Can you explain the step-by-step evaluation process involving type coercion and operator precedence?
The JavaScript expression ++[[]][+[]]+[+[]] evaluates to the string “10” through a complex process involving type coercion, operator precedence, and JavaScript’s implicit conversion rules. The evaluation follows specific steps where empty arrays are converted to numbers, the increment operator is applied, and finally string concatenation occurs between the numeric result and an array.
Contents
- Breaking Down the Expression
- Step-by-Step Evaluation Process
- Type Coercion Rules
- Operator Precedence
- Why String Concatenation Occurs
- Practical Examples and Verification
Breaking Down the Expression
The expression ++[[]][+[]]+[+[]] can be understood by analyzing its components:
[[]]- An array containing one element: an empty array[]+[]- Unary plus operator applied to an empty array[+[]]- An array containing the result of+[]++- Increment operator+- Binary addition operator
Step-by-Step Evaluation Process
Let’s trace through the evaluation step by step:
-
+[]evaluation:- The unary plus operator
+converts the empty array[]to a number - An empty array converts to the number
0through JavaScript’s type coercion - So
+[]evaluates to0
- The unary plus operator
-
[+[]]evaluation:- This creates an array containing the result of
+[] - Since
+[]is0,[+[]]becomes[0]
- This creates an array containing the result of
-
[[]][+[]]evaluation:- We access the element at index
+[](which is0) of the array[[]] [[]]contains one element at index 0: the empty array[]- Therefore,
[[]][+[]]evaluates to[](an empty array)
- We access the element at index
-
++[[]][+[]]evaluation:- The increment operator
++is applied to the empty array[] - JavaScript first converts the empty array to a number for the increment operation
- An empty array converts to
0, so we’re essentially doing++0 - This evaluates to
1
- The increment operator
-
Final addition
++[[]][+[]]+[+[]]:- We now have
1 + [0] - JavaScript’s binary
+operator with mixed types performs string concatenation 1converts to string"1"[0]converts to string"0"- The result is
"1" + "0" = "10"
- We now have
Type Coercion Rules
The evaluation relies heavily on JavaScript’s type coercion rules:
-
Array to Number Conversion: When an array needs to be converted to a number, JavaScript first calls its
valueOf()method, which returns the array itself. Since this isn’t a primitive, JavaScript then callstoString(), which returns an empty string"". This empty string is then converted to the number0. -
Array to String Conversion: When an array is converted to a string, JavaScript calls its
toString()method, which joins all elements with commas. For[0], this results in"0". -
Binary + Operator Behavior: According to MDN documentation, the binary
+operator performs numeric addition if both operands are numbers. If either operand is a string, it performs string concatenation after converting both operands to strings.
Operator Precedence
The evaluation order is determined by JavaScript’s operator precedence rules:
- Unary
+has higher precedence than binary+ - Increment
++has higher precedence than binary+ - Array indexing
[]has higher precedence than both++and+
The expression is effectively parsed as:
++( [ [ ] ] [ + [ ] ] ) + ( + [ ] )
This means:
- Array indexing is performed first
- Then the unary increment
- Finally the binary addition
Why String Concatenation Occurs
The final result becomes a string because of how JavaScript handles the binary + operator with mixed types:
When using the binary
+operator with mixed types, if either operand is a string, JavaScript performs string concatenation rather than numeric addition.
In our case:
++[[]][+[]]evaluates to the number1[+[]]evaluates to the array[0]
When we perform 1 + [0]:
- JavaScript converts both operands to strings
1becomes"1"[0]becomes"0"(via array’stoString()method)- The result is string concatenation:
"1" + "0" = "10"
This behavior is consistent with JavaScript’s type coercion rules where the binary + operator prioritizes string concatenation when string types are involved.
Practical Examples and Verification
You can verify this behavior by testing individual components:
// Test individual parts
console.log(+[]); // 0
console.log([+[]]); // [0]
console.log([[]][+[]]); // []
console.log(++[[]][+[]]); // 1 (in a proper context)
console.log([+[]]); // [0]
// Test the final result
console.log(++[[]][+[]] + [+[]]); // "10"
console.log(typeof(++[[]][+[]] + [+[]])); // "string"
The expression demonstrates several important JavaScript concepts:
- Type conversion and coercion
- Operator precedence
- Array behavior in different contexts
- The nuanced behavior of the
+operator
This is why what appears to be a mathematical expression actually results in a string value through JavaScript’s implicit type conversion rules.