没有“意外令牌非法”的明显原因

我在控制台上收到此 JavaScript 错误:

未捕获的语法错误:意外的令牌非法

这是我的代码:

var foo = 'bar';​

正如你所看到的,这非常简单。它如何导致语法错误?


答案 1

错误

当代码被JavaScript解释器解析时,它会被分解成称为“令牌”的片段。当令牌无法分类为四种基本令牌类型之一时,在大多数实现上,它被标记为“非法”,并引发此错误。

例如,如果您尝试运行带有流氓字符,放错位置的大括号,括号,“智能引号”,未正确括起来的单引号(例如)等的js文件,则会引发相同的错误。@this.run('dev1)

许多不同的情况都可能导致此错误。但是,如果您没有任何明显的语法错误或非法字符,则可能是由不可见的非法字符引起的。这就是这个答案的意义所在。

但我看不到任何非法的东西!

代码中有一个不可见的字符,紧跟在分号之后。它是 Unicode U+200B 零宽度空格字符(又名 HTML 实体)。已知该字符会导致 JavaScript 语法错误。ZWSP​Unexpected token ILLEGAL

它从何而来?

我不能确定,但我的赌注是在jsfiddle上。如果从那里粘贴代码,则很可能包含一个或多个字符。该工具似乎使用该字符来控制长字符串上的自动换行。U+200B

更新 2013-01-07

在最新的jsfiddle更新之后,它现在像codepen一样将字符显示为红点显然,它也不再自己插入字符,所以从现在开始,这个问题应该不那么频繁了。U+200B

更新 2015-03-17

由于VirtualBox中的错误,Vagrant似乎有时也会导致此问题。根据这篇博客文章,解决方案是在nginx配置中设置,或者如果您使用Apache。sendfile off;EnableSendfile Off

据报道,从Chrome开发人员工具粘贴的代码可能包含该字符,但我无法使用当前版本(OSX上的22.0.1229.79)重现该字符。

我怎样才能发现它?

这个角色是看不见的,我们怎么知道它在那里?您可以要求编辑器显示不可见的字符。大多数文本编辑器都具有此功能。例如,Vim 默认显示它们,而 显示为 。您也可以在线调试它:jsbin在其代码窗格上将字符显示为红点(但在保存并重新加载页面后似乎将其删除)。CodePen.io 还会将其显示为点,即使在保存后仍保留它。ZWSP<u200b>

相关问题

这个角色并不坏,它实际上非常有用。维基百科上的这个例子演示了如何使用它来控制长字符串应该在何处换行到下一行。但是,如果您不知道标记上存在该字符,则可能会成为问题。如果将其放在字符串中(例如,没有可见内容的DOM元素),则可能会期望此类字符串为空,而实际上它不是(即使在应用之后)。nodeValueString.trim

ZWSP还可能导致在HTML页面上显示额外的空格,例如,当它在两个元素之间找到时(如本问题所示)。这种情况甚至在jsfiddle上都不可重现,因为该字符在那里被忽略。<div>

另一个潜在的问题:如果网页的编码未被识别为UTF-8,则实际上可能会显示该字符(例如,在latin1中)。​

如果 CSS 代码(内联代码或外部样式表)上存在,则样式也无法正确解析,因此某些样式不会被应用(如本问题所示)。ZWSP

ECMAScript 规范

我在 ECMAScript 规范(版本 35.1)上找不到任何提及该特定字符的内容。当前版本在第 7.1 节中提到了类似的字符 ( 和 ),该节表示,当“在注释、字符串文本和正则表达式文本之外”时,应将它们视为 s。例如,这些字符可能是变量名称的一部分(并且确实有效)。U+200CU+200DIdentifierPartvar x\u200c;

第7.2节列出了有效的空格字符(如制表符,空格,不换行空格等),并含糊地提到任何其他Unicode“空格分隔符”(类别“Zs”)都应被视为空格。我可能不是在这方面讨论规范的最佳人选,但在我看来,应该根据这一点考虑空白,而实际上实现(至少Chrome和Firefox)似乎将它们视为意外的令牌(或令牌的一部分),从而导致语法错误。U+200B


答案 2

为什么你在代码中寻找这个问题?甚至,如果它是复制粘贴的。

如果你能看到,在同步文件夹中保存文件后究竟发生了什么 - 你会在文件末尾看到类似的东西。它与您的代码完全无关。*****

溶液。

如果您在流浪箱中使用 - 添加到服务器配置:nginx

sendfile off;

如果您在流浪箱中使用 - 添加到服务器配置:apache

EnableSendfile Off;

问题来源:VirtualBox Bug