How That Crazy JS One‑Liner Turns Into “sb”: A Deep Dive into Type Coercion
This article explains why a seemingly nonsensical JavaScript expression evaluates to the two characters “sb” by dissecting its operator precedence, breaking it into sub‑expressions, and applying JavaScript’s type‑conversion rules step by step.
The author encountered a puzzling JavaScript one‑liner shared in a chat group and decided to uncover why it produces the surprising output “sb”. The original code is:
(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]Running the code yields the characters “sb”, which the author uses to mock anyone who underestimates JavaScript.
Operator Precedence
Understanding the expression starts with JavaScript’s operator precedence. The article provides a precedence table (image) and shows how the long expression can be split into 16 smaller sub‑expressions (image).
Note that brackets [] act as an operator for array indexing and string character access, and they have the highest precedence.
Type‑Conversion Rules
The next step is applying JavaScript’s type‑conversion mechanisms. The article outlines the three main conversion functions:
ToPrimitive(input, PreferredType?) – converts objects to primitive values, preferring Number or String based on the optional hint.
ToNumber() – converts a value to a Number according to ECMA‑262 §9.3 (illustrated with an image).
ToString() – converts a value to a String according to ECMA‑262 §9.8 (illustrated with an image).
Step‑by‑Step Evaluation
Sub‑expression 16: +[] – The empty array is first converted to a primitive (via valueOf, which returns the array itself), then to a string (""), and finally to a number, yielding 0.
Sub‑expression 15: [~+""] – The empty string becomes 0, the unary ~ (bitwise NOT) turns 0 into -1. Wrapped in brackets, the result is the array [-1].
Sub‑expression 13 combines the results of 15 and 16 to form –[-1][0], which accesses the first element of the array ( -1) and then applies the prefix decrement, yielding -2.
Sub‑expression 14: [~+[]] follows the same logic as 15, also producing [-1].
Sub‑expression 9: -2*[-1] – The array [-1] is coerced to the string "-1", then to the number -1, and multiplied by -2 to give 2.
Sub‑expression 10: ~~!+[] – +[] becomes 0, !0 is true, and applying ~ twice yields 1.
With sub‑expressions 9 and 10 evaluated, sub‑expression 4 simplifies to 2+1, which equals 3.
Sub‑expression 7: !(~+[]) – +[] is 0, ~0 is -1, and logical NOT of -1 yields false.
Sub‑expression 3: false+{} – The object is converted to the string "[object Object]"; false becomes the string "false"; concatenation results in "false[object Object]".
Sub‑expression 1: "false[object Object]"[3] – Indexing the string at position 3 extracts the character s. The same process applied to the remaining part of the original expression yields the character b, completing the output "sb".
Conclusion
By systematically applying operator precedence and JavaScript’s type‑conversion rules, the seemingly magical expression is demystified. Mastering these concepts enables developers to decode similar obfuscated snippets instantly.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
