我正在看a talk on JSON hijacking而不是2分钟,我已经不熟悉JavaScript了。
let:let{let:[x=1]}=[alert(1)]
它似乎适用于Edge而只是警告1
,但我从来没有遇到let:let
语法。我很好奇,我怎么读这个?
答案 0 :(得分:4)
该视频实际上表示它使用了destructuring assignment和labels。
此代码似乎不适用于Edge以外的浏览器;所以为了使它在其他浏览器中工作,它需要看起来像这样:
let:{let{let:[x=1]}=[alert(1)]}
为什么呢?我们来看看Firefox的控制台:
SyntaxError: lexical declarations can't appear in single-statement context
错误所指的“单一语句上下文”是开头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] is a reserved identifier
而失败。
现在,代码的剩余部分使用了解构:
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];
现在,我们尝试获取let
的{{1}}属性,该属性本身为[undefined]
。此外,该行试图获取该属性的值,并将其进一步解构为数组(因此该值必须是可迭代对象),其第一个元素具有变量名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
。
部分混淆可能源于嵌套解构,就像这两个片段一样:
undefined
let {a: {b: {c}}} = {a: {b: {c: 3}}}
此处,未创建变量let {a: {b: {c = 1}}} = {a: {b: {c: 3}}}
或a
,仅b
,标识符不后跟c
左手边。 :
后面的属性名称基本上指示“在右侧值中找到此属性。