【问题标题】:Why does "3 [1, 2];" return undefined in JavaScript?为什么“3 [1, 2];”在 JavaScript 中返回未定义?
【发布时间】:2013-01-15 20:50:43
【问题描述】:

我正在查看 GMail 执行的一些 AJAX 调用,我注意到有时调用的返回值以数字开头。示例:(注意第一行后面没有分号)

3 
[1, 2];

如果我将它输入到 JavaScript 控制台,我会得到 undefined 返回。但是,如果第二个参数是数字或字符串,我会返回第二个参数。示例:

3
4

返回 4。

我的猜测是他们这样做是为了阻止 jsonp 类型的攻击,但是,有谁知道正在进行什么基础评估?在第二种情况下,我相信在第一行之后“插入”一个分号,这将使返回 4 有意义。但是,我想不出第一个表达式会返回 undefined 的原因。

【问题讨论】:

  • 并且在安全性方面(谷歌可能已经意识到这一点并放置了一个无意义的最后一个元素或其他东西)这实际上比 {"d":} 包装器要糟糕得多 - 通过在Number 原型,可以确定最后一个元素的内容是否匹配某个值。 (因此,如果有人打算这样做以修复 Firefox 2- 错误...请注意!=)
  • (是的,看起来 Gmail 中的最后一个数字总是0。无论如何...)
  • 啊,因为逗号运算符将返回其集合中的最后一个元素。很有趣。

标签: javascript json jsonp


【解决方案1】:

这是因为 ASI(自动分号插入)的工作原理。第一条语句被解释为

3[1,2];

所以它是undefined。第二个被 ASI 解释为3;4;,即4

ASI 规则在某些情况下是违反直觉的,例如您可能想知道为什么数字和括号之间没有分号?嗯,这是有原因的。阅读这些资源了解更多详情:

What are the rules for JavaScript's automatic semicolon insertion (ASI)?

http://bclary.com/2004/11/07/#a-7.9.1

Google 可能会为您提供更多结果。 :) 这就是为什么我们有无休止的无分号 JavaScript 战争。

【讨论】:

  • @Bergi 啊,我明白了,属性访问 :) 一定很喜欢 {}[]() 在 JS 中的多重含义。
  • @freakish:您能指出具体的 ASI 规则吗?
  • 123['foo'] - Number 文字的属性访问。谢谢,布伦丹把这个放进去。:P
  • +1 在控制台中输入:['a', 'b', 'c'] [1,2](中间有一个 \n):你得到'c'。这证实了freakish 的发现。
  • @Bergi 据我所知,只有在遇到违规标记时才会插入分号。在这种情况下,[3 之后没有违规,因此引擎不会执行 ASI。
【解决方案2】:

这是为了防止 Ajax JSON hack 更改 Array 构造函数。这是一个老错误,与现代浏览器无关,但必须加以处理。

hack 覆盖了 Array 构造函数,因此当读取 JSON 时,代码将执行构造函数所做的事情。更多解释在这里:http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

顺便说一句,这就是 ASP.NET 总是发回此类对象的原因:{d: []}

【讨论】:

  • 我认为 OP 知道这一点,但实际的问题是“为什么第一个语句返回 undefined 而第二个没有
  • @Bergi 哦,那我的错。我留下答案,因为它回答了他的部分问题。
猜你喜欢
  • 1970-01-01
  • 2023-01-16
  • 2019-01-09
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
相关资源
最近更新 更多