The video actually says that it uses destructuring assignment and labels.
This code doesn’t appear to work in browser other than Edge; so to make it work in other browsers, it needs to look like this:
let:{let{let:[x=1]}=[alert(1)]}
Why? Let’s look at Firefox’s console:
SyntaxError: lexical declarations can't appear in single-statement context
The “single-statement context” the error is referring to, is the part after let:
at the beginning — let{let:[x=1]}=[alert(1)]
. In this case, the let
before it is a label. No other keywords appear to work as a label:
var: while(false); // => SyntaxError: missing variable name
for: while(false); // => SyntaxError: missing ( after for
However, a few of them work:
yield: while(false);
async: while(false);
await: while(false);
In strict mode however, let
and yield
would fail as well with SyntaxError:
[keyword] is a reserved identifier
.
Now, the remaining part of the code uses destructuring:
let {
let: [x = 1]
} = [
alert(1)
];
The let
inside the {
}
just signifies an object property, which is totally fine. The following is valid JS:
let object = {
let: 2,
var: 1,
const: "hello",
while: true,
throw: Error
};
alert(1)
gets executed, so you see the alert. It evaluates to undefined
, so you have:
let {let: [x = 1]} = [undefined];
Now, this is trying to get the let
property of [undefined]
, which itself is undefined
. Further, this line is attempting to take the value of that property, and destructure it further into an array (so the value has to be an iterable object) with the variable name x
for its first element, with the default value 1
. Since [undefined].let
is undefined
, it can’t be destructured, so the code throws the error:
TypeError: [...].let is undefined
Working destructuring could look like one of these lines:
let {let: [x = 1]} = {let: [alert(1)]}; // x is now 1 (default value, since first element in right-hand side is undefined)
let {let: [x = 1]} = {let: [2]}; // x is now 2 (defined due to right-hand side)
Both don’t throw an error, and the first one assigns 1
to x
, because the first element in the array on the right-hand side was undefined
.
Part of the confusion may stem from nested destructuring, like these two snippets:
let {a: {b: {c}}} = {a: {b: {c: 3}}}
let {a: {b: {c = 1}}} = {a: {b: {c: 3}}}
Here, no variables a
or b
are created, only c
, which is the identifier not followed by a :
on the left-hand side. Property names that are followed by a :
basically instruct the assignment to “find this property in the right-hand side value”.
let:{ let{let:[x=1]}=[alert(1)] }
if that helps - firstlet
is a label, secondlet
is an actuallet
and thirdlet
is a property name (sort of) - hmmm, maybe not that simple actually - though, there are errors in the console for edgelet
as a label there.1