Javascript 为什么2+ ;40等于42?

Javascript 为什么2+ ;40等于42?,javascript,unicode,Javascript,Unicode,当一位同事向我展示这一行JavaScript时,我感到困惑 警报(2)+ 40);该字符是,它是一个空格字符。因此,该代码相当于警报(2+40) 我还想知道是否有更多的角色表现得像这样 Zs类中的任何Unicode字符 但是,它允许您使用有趣的变量名,如ಠ_ಠ我想它与这样一个事实有关:出于某种奇怪的原因,它被归类为空白: $ unicode   U+1680 OGHAM SPACE MARK UTF-8: e1 9a 80 UTF-16BE: 1680 Decimal: &#576

当一位同事向我展示这一行JavaScript时,我感到困惑

警报(2)+ 40);该字符是,它是一个空格字符。因此,该代码相当于
警报(2+40)

我还想知道是否有更多的角色表现得像这样

Zs类中的任何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为什么会这样做

您使用的字符实际上是空白字符,因此它基本上被解释为与空格相同的东西,这意味着您的语句看起来像Javascript的
alert(2+40)

Javascript中还有其他类似的字符。您可以看到完整的列表


关于这个字符,我注意到了一个有趣的地方,那就是Google Chrome(可能还有其他浏览器)在页面顶部栏中对其进行解释的方式

它是一个内部有
1680
的块。这实际上是ogham空格标记的unicode数字。这似乎只是我的机器在做这件事,但这是一件奇怪的事情


我决定用其他语言尝试一下,看看会发生什么,这些就是我得到的结果


无法使用的语言: Python 2和3

>> 2+ 40
  File "<stdin>", line 1
    2+ 40
        ^
SyntaxError: invalid character in identifier
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
开始

>> 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.
C# (在
Main()方法中)

Perl 6

>> ./perl6 -e'say 2+ 40' 
42

在阅读了其他答案之后,我编写了一个简单的脚本来查找U+0000–U+FFFF范围内的所有类似空格的Unicode字符。看起来,根据浏览器的不同,其中有26或27个,对于U+0085和U+FFFE存在分歧

请注意,这些字符中的大多数看起来就像一个常规的空白

函数isSpace(ch)
{
尝试
{
返回函数('return 2+'ch+'2')()==4;
}
捕获(e)
{
返回false;
}
}
对于(var i=0;i
我还想知道是否有更多的角色表现得像这样

我似乎记得不久前读过一篇文章,讲的是用希腊问号U+037E恶作剧地替换某人代码中的分号(U+003B)

它们看起来都一样(在某种程度上,我相信希腊人自己使用U+003B),但本文指出另一个不起作用

有关这方面的更多信息,请访问维基百科:

还有一个(封闭的)问题,是关于把这当作是SO本身的恶作剧。但我最初读到的地方不是这样的:

Ubuntu不是问题所在。您使用的窗口标题字体是。firefox(iceweasel)和debian上的google chrome似乎显示unicode字符很好,尽管我已经竭尽全力确保系统上的unicode兼容性。(事实上,我做的最有用的事情是最简单的:
sudo apt get install unicode
,尽管只是经过数小时的研究和失败的尝试)@PSkocik有趣的是,我以前在这里遇到过字体问题,所以这可能是likely@PSkocik“Ubuntu不是问题。您使用的窗口标题字体是。”…这是“”@PSkocik I最终修复了它:)只需要更改系统标题栏字体。@Elyasin您复制/粘贴或重新键入了吗?这在Visual C#中也适用。当将奇怪字符粘贴到Visual Studio IDE中,或通过键入
完成语句时,编辑器倾向于更改奇怪字符` ` 将字符转换为普通空格,但如果撤消该“自动更正”,则具有相同的行为。该字符与空格具有相同的语义,即使它看起来像连字符或减号(在通常的字体中)。也可能发生相反的情况。在标识符中支持unicode的某些语言接受看起来像空白的unicode字符(换句话说,你看不到它们);甚至可能有完全不可见的标识符。(OT)因为42是所有问题的答案?@Thomas意外的结果是由Unicode字符引起的这一事实已经很清楚了。Box-with-a-hex-code下划线Box-with-a-hex-code。它应该是哪个字符?@immibis这个答案的最后一部分是图像形式的表情符号,请注意,不仅仅是
Zs
字符在JavaScript中被认为是空白。还有更多:当
ಠ_ಠ可用作JS中的标识符:ಠ_ಠ@在C风格的语言中,被视为字母的chriscifice下划线由来已久。
被视为一个字母只是常识,因为它是一个字母。如果
ಠ_ಠ
不能用作标识符。U+0085“NEL”被Unicode定义为空白,但有很长的错误处理历史。U+FFFE是一个非字符,除了NChar之外没有名称和属性,不应该被任何合理的东西视为空白。也就是说,我的浏览器在这两个方面都与我不一致:)@霍布斯U+FFFE也是一个
\p{Default Ignorable code Point}
,而不仅仅是一个
\p{Noncharacter code pound}
。U+0085一直是一个
\p{Whitespace}
代码点。邪恶的是U+180E蒙古语元音分隔符,“最近”失去了
\p{Whitespace}
属性。请注意
\p{Pattern Whitespace}
是一个小得多的集合,是一个不可变的属性。但
\p{Whitespace}
不是。
FEFF
是BOM,可以像文本中的“零宽度无中断空间”一样处理。
FFF
>> 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 -e'2+ 40'                                                                                                                                   
Unrecognized character \xE1; marked by <-- HERE after 2+<-- HERE near column 3 at -e line 1.
>> (+ 2  40)
=> 42
Console.WriteLine(2+ 40);

Output: 42
>> ./perl6 -e'say 2+ 40' 
42