`let:let{let:[x=1]}=[alert(1)]` 会发生什么?
What happens in `let:let{let:[x=1]}=[alert(1)]`?
我在看a talk on JSON hijacking 不到2分钟,已经有JavaScript我不熟悉了
let:let{let:[x=1]}=[alert(1)]
它似乎可以在 Edge 上运行并且只是提醒 1
,但我从来没有遇到过 let:let
语法。我很好奇,我该如何阅读?
视频实际上说它使用 destructuring assignment and labels。
此代码似乎无法在 Edge 以外的浏览器中运行;所以为了让它在其他浏览器中工作,它需要看起来像这样:
let:{let{let:[x=1]}=[alert(1)]}
为什么?让我们看看 Firefox 的控制台:
SyntaxError: lexical declarations can't appear in single-statement context
错误所指的“single-statement上下文”,是let:
开头的那部分 — let{let:[x=1]}=[alert(1)]
。在这种情况下,它前面的 let
是一个 标签 。似乎没有其他关键字可以用作标签:
var: while(false); // => SyntaxError: missing variable name
for: while(false); // => SyntaxError: missing ( after for
但是,其中一些有效:
yield: while(false);
async: while(false);
await: while(false);
然而,在 strict mode 中,let
和 yield
也会因 SyntaxError:
[keyword] [=27 而失败=].
现在,代码的剩余部分使用解构:
let {
let: [x = 1]
} = [
alert(1)
];
{
}
里面的let
只是表示一个对象属性,完全没问题。以下为有效JS:
let object = {
let: 2,
var: 1,
const: "hello",
while: true,
throw: Error
};
alert(1)
被执行,因此您会看到警报。它的计算结果为 undefined
,因此您有:
let {let: [x = 1]} = [undefined];
现在,这是试图获取 [undefined]
的 let
属性,它本身就是 undefined
。此外,此行试图获取 属性 的值,并将其进一步解构为数组(因此该值必须是可迭代对象),其第一个元素的变量名称为 x
,使用默认值 1
。由于[undefined].let
是undefined
,无法解构,所以代码抛出错误:
TypeError: [...].let is undefined
正在工作 解构可能看起来像这些行之一:
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)
两个都不报错,第一个把1
赋值给x
,因为right-hand这边的数组第一个元素是undefined
.
部分混淆可能源于嵌套解构,如以下两个片段:
let {a: {b: {c}}} = {a: {b: {c: 3}}}
let {a: {b: {c = 1}}} = {a: {b: {c: 3}}}
这里,没有创建变量a
或b
,只有c
,也就是标识符not后跟一个:
在 left-hand 一侧。 属性 后跟 :
的名称基本上指示赋值给 “在 right-hand 边值中找到这个 属性”。
我在看a talk on JSON hijacking 不到2分钟,已经有JavaScript我不熟悉了
let:let{let:[x=1]}=[alert(1)]
它似乎可以在 Edge 上运行并且只是提醒 1
,但我从来没有遇到过 let:let
语法。我很好奇,我该如何阅读?
视频实际上说它使用 destructuring assignment and labels。
此代码似乎无法在 Edge 以外的浏览器中运行;所以为了让它在其他浏览器中工作,它需要看起来像这样:
let:{let{let:[x=1]}=[alert(1)]}
为什么?让我们看看 Firefox 的控制台:
SyntaxError: lexical declarations can't appear in single-statement context
错误所指的“single-statement上下文”,是let:
开头的那部分 — let{let:[x=1]}=[alert(1)]
。在这种情况下,它前面的 let
是一个 标签 。似乎没有其他关键字可以用作标签:
var: while(false); // => SyntaxError: missing variable name
for: while(false); // => SyntaxError: missing ( after for
但是,其中一些有效:
yield: while(false);
async: while(false);
await: while(false);
然而,在 strict mode 中,let
和 yield
也会因 SyntaxError:
[keyword] [=27 而失败=].
现在,代码的剩余部分使用解构:
let {
let: [x = 1]
} = [
alert(1)
];
{
}
里面的let
只是表示一个对象属性,完全没问题。以下为有效JS:
let object = {
let: 2,
var: 1,
const: "hello",
while: true,
throw: Error
};
alert(1)
被执行,因此您会看到警报。它的计算结果为 undefined
,因此您有:
let {let: [x = 1]} = [undefined];
现在,这是试图获取 [undefined]
的 let
属性,它本身就是 undefined
。此外,此行试图获取 属性 的值,并将其进一步解构为数组(因此该值必须是可迭代对象),其第一个元素的变量名称为 x
,使用默认值 1
。由于[undefined].let
是undefined
,无法解构,所以代码抛出错误:
TypeError: [...].let is undefined
正在工作 解构可能看起来像这些行之一:
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)
两个都不报错,第一个把1
赋值给x
,因为right-hand这边的数组第一个元素是undefined
.
部分混淆可能源于嵌套解构,如以下两个片段:
let {a: {b: {c}}} = {a: {b: {c: 3}}}
let {a: {b: {c = 1}}} = {a: {b: {c: 3}}}
这里,没有创建变量a
或b
,只有c
,也就是标识符not后跟一个:
在 left-hand 一侧。 属性 后跟 :
的名称基本上指示赋值给 “在 right-hand 边值中找到这个 属性”。