为什么 <!-- 不会抛出语法错误?

10

我在一些遗留代码中注意到了以下模式:

<script>
    <!--
    // code
    // -->
</script>

经过一些研究,这似乎是一种非常古老的技术,用于在浏览器不支持<script>元素时隐藏脚本元素的内容。更多信息可以在这里找到。

我的关注点是:为什么<!--不会抛出语法错误?我在whatwg.org的网站上发现,<!--应该与//在功能上等效,并引用了来自有关注释的ECMAScript语法的片段。问题是,该语法根本没有定义<!--

因此,这似乎是所有主要浏览器都实现的未定义行为。是否有允许这样做的规范,或者这是人们正在推进的向后兼容性hack?


这不是JS的一部分,它是HTML的一部分。 - nnnnnn
它也适用于外部脚本文件。@nnnnnn,为什么HTML解析器会解释我的JavaScript?看起来很可疑。 - raynjamin
它在Node的REPL中可以工作,所以我怀疑这不仅仅是HTML的问题。 - raina77ow
2
有趣的是,在代码中间它似乎被悄悄地忽略了。例如:http://jsfiddle.net/4cegngew/ 如果我在任意两行之间加入其他语法错误,我会看到控制台报告其他错误,但我根本看不到“注释”行被报告。 - David
Raynjamin - 我会说 HTML 解析器没有解释你的 JS,但它必须找出文件中哪部分实际上是 JS,才能将其传递给 JS 引擎,所以...(不幸的是,这并不能解释为什么它在外部脚本文件中可以工作。) - nnnnnn
显示剩余3条评论
2个回答

5
官方解释:因为HTML规范中有特定的处理方式,例如这是一个“凭信仰”之物。这不是JavaScript的事情,在JavaScript语法中找不到它。
非官方地说,至少一些JavaScript引擎会固有地处理它,有时以使我认为有效的JavaScript无效的方式。例如,在浏览器中的V8上,这将失败:

eval("var a = 1; var n = 3; console.log(a<!--n);")

...出现 意外的输入结束 错误。我非常确定它 不应该 出现,但我不是一个解析法律专家。我希望它像这样在控制台上记录 false

eval("var a = 1; var n = 3; console.log(a<! --n);")
// Note the space -------------------------^

顺带一提:Meteor的jsparser也同意我的看法,只需将双引号内的部分复制粘贴到其中即可。

请注意,在规范中没有出现字符<!,在其中70次出现单词“comment”的附近也没有任何东西,也不会出现在注释语法中的任何地方,因此它似乎不是显式的规范例外。这只是一些JavaScript引擎为避免人们做傻事而执行的操作。毫不奇怪。:-)


1
那为什么在浏览器的控制台中或者Node.js REPL中使用就可以呢? - raina77ow
1
@raina77ow 个人而言,我认为这是一个“显然不是JS语法的情况,所以我可以安全地假设你想要表达什么,并继续愉快地进行下去”。 - Niet the Dark Absol
1
据我所知,官方上来说这只是一个浏览器的事情。但是如果JavaScript引擎在解析某些东西时允许这样做,我一点也不感到惊讶。这就是实用主义。 - T.J. Crowder
1
那么 eval('3 + 3<!--'); 呢? - raina77ow
2
@NiettheDarkAbsol var x = ({a:function(c){this.b.push(c);return c?this.a(--c):this.b;},b:[]}.a(~+!"">>>+!""));在JS中,我总是会暂停一下,思考“这显然不是有效的语法”。 - raynjamin
显示剩余17条评论

1

这是用户代理的W3文档定义:

JavaScript引擎允许字符串"<!--"出现在SCRIPT元素的开头,并忽略直到行尾的其他字符。

因此,浏览器遵循这些标准。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接