当一位同事向我展示这一行JavaScript提醒42时,我感到很困惑。
警报(2+ 40);
很快就会发现,看起来像负号的东西实际上是一个神秘的Unicode字符,具有明显不同的语义。
这让我想知道为什么在解析表达式时,该字符没有产生语法错误。我还想知道是否有更多的角色有这样的行为。
当一位同事向我展示这一行JavaScript提醒42时,我感到很困惑。
警报(2+ 40);
很快就会发现,看起来像负号的东西实际上是一个神秘的Unicode字符,具有明显不同的语义。
这让我想知道为什么在解析表达式时,该字符没有产生语法错误。我还想知道是否有更多的角色有这样的行为。
当前回答
我还想知道是否有更多的角色有这样的行为。
我似乎记得前阵子读过一篇文章,说有人恶作剧地用希腊问号U+037E替换代码中的分号(U+003B)。
它们看起来是一样的(在某种程度上,我相信希腊人自己使用U+003B),但这篇文章指出,另一个不合适。
更多关于这方面的信息,维基百科在这里:https://en.wikipedia.org/wiki/Question_mark#Greek_question_mark
还有一个(封闭的)关于使用这个作为恶作剧的问题。不是我最初读到它的地方。 JavaScript恶作剧/笑话
其他回答
该字符是“OGHAM SPACE MARK”,这是一个空格字符。所以代码相当于alert(2+ 40)。
我还想知道是否有更多的角色有这样的行为。
Zs类中的任何Unicode字符都是JavaScript中的空白字符,但似乎没有那么多。
然而,JavaScript也允许在标识符中使用Unicode字符,这允许您使用有趣的变量名,如ಠ_ಠ。
我猜这和它被归类为空白的原因有关:
$ unicode
U+1680 OGHAM SPACE MARK
UTF-8: e1 9a 80 UTF-16BE: 1680 Decimal:  
( )
Uppercase: U+1680
Category: Zs (Separator, Space)
Bidi: WS (Whitespace)
看起来,您正在使用的字符实际上比实际的负号(连字符)长。
-
上面是你要用的,下面是负号。你似乎已经知道了这一点,所以现在让我们看看Javascript为什么这样做。
您使用的字符实际上是ogham空格标记,这是一个空白字符,因此它基本上被解释为空格,这意味着您的语句看起来像alert(2+ 40)对于Javascript。
Javascript中还有其他类似的字符。你可以在维基百科上看到完整的列表。
有趣的是,我注意到谷歌Chrome浏览器(可能还有其他浏览器)在页面顶部栏解释它的方式。
这是一个里面有1680人的街区。这实际上是unicode中ogham空格符号的编号。这似乎只是我的机器在做这件事,但这是一件奇怪的事情。
我决定在其他语言中尝试这个方法,看看会发生什么,下面是我得到的结果。
无法使用的语言:
Python 2和3
>> 2+ 40
File "<stdin>", line 1
2+ 40
^
SyntaxError: invalid character in identifier
Ruby
>> 2+ 40
NameError: undefined local variable or method ` 40' for main:Object
from (irb):1
from /home/michaelpri/.rbenv/versions/2.2.2/bin/irb:11:in `<main>'
Java(在主方法内部)
>> System.out.println(2+ 40);
Main.java:3: error: illegal character: \5760
System.out.println(2+?40);
^
Main.java:3: error: ';' expected
System.out.println(2+?40);
^
Main.java:3: error: illegal start of expression
System.out.println(2+?40);
^
3 errors
PHP
>> 2+ 40;
Use of undefined constant 40 - assumed ' 40' :1
C
>> 2+ 40
main.c:1:1: error: expected identifier or '(' before numeric constant
2+ 40
^
main.c:1:1: error: stray '\341' in program
main.c:1:1: error: stray '\232' in program
main.c:1:1: error: stray '\200' in program
exit status 1
Go
>> 2+ 40
can't load package: package .:
main.go:1:1: expected 'package', found 'INT' 2
main.go:1:3: illegal character U+1680
exit status 1
Perl 5
>> perl -e'2+ 40'
Unrecognized character \xE1; marked by <-- HERE after 2+<-- HERE near column 3 at -e line 1.
它适用的语言:
计划
>> (+ 2 40)
=> 42
c# (在Main()方法内)
Console.WriteLine(2+ 40);
Output: 42
Perl 6
>> ./perl6 -e'say 2+ 40'
42
在阅读了其他答案后,我编写了一个简单的脚本,以查找U+ 0000-U +FFFF范围内所有表现为空格的Unicode字符。看起来,根据浏览器的不同,有26或27个,对U+0085和U+FFFE存在分歧。
注意,这些字符中的大多数看起来就像一个普通的空白。
function isSpace (ch) 可不, 我会用 可不, return Function(‘return 2 +’+ ch +‘2’)()= = = 4; 出于美观 于我(e) 可不, return false; 出于美观 出于美观 对于(vari=0;i <= 0xff;+ + i) 可不, varch=string.fromcharcode (i) (isSpace (ch)真有极乐世界) 可不, document.body.appendChild (document.createElement(‘dave’))。textContent =‘U + +(’‘万+ i.toString’(16).toUpperCase ()) .slice (-4 ) + ' "' + ch +’‘;” 出于美观 出于美观 font-family: monospace;出于美观
我还想知道是否有更多的角色有这样的行为。
我似乎记得前阵子读过一篇文章,说有人恶作剧地用希腊问号U+037E替换代码中的分号(U+003B)。
它们看起来是一样的(在某种程度上,我相信希腊人自己使用U+003B),但这篇文章指出,另一个不合适。
更多关于这方面的信息,维基百科在这里:https://en.wikipedia.org/wiki/Question_mark#Greek_question_mark
还有一个(封闭的)关于使用这个作为恶作剧的问题。不是我最初读到它的地方。 JavaScript恶作剧/笑话