为什么2 + 40等于42?

本文翻译自:Why does 2+ 40 equal 42?

I was baffled when a colleague showed me this line of JavaScript alerting 42. 当一位同事向我展示这一行警告42时,我感到很困惑。

 alert(2+ 40); 

It quickly turns out that what looks like a minus sign is actually an arcane Unicode character with clearly different semantics. 事实证明,看起来像减号的实际上是一个神秘的Unicode字符,具有明显不同的语义。

This left me wondering why that character doesn't produce a syntax error when the expression is parsed. 这让我想知道为什么该字符在解析表达式时不会产生语法错误。 I'd also like to know if there are more characters behaving like this. 我还想知道是否有更多的人物表现得像这样。


#1楼

参考:https://stackoom.com/question/28CRj/为什么-等于


#2楼

That character is "OGHAM SPACE MARK" , which is a space character. 那个角色是“OGHAM SPACE MARK” ,这是一个空间角色。 So the code is equivalent to alert(2+ 40) . 所以代码相当于alert(2+ 40)

I'd also like to know if there are more characters behaving like this. 我还想知道是否有更多的人物表现得像这样。

Any Unicode character in the Zs class is a white space character in JavaScript , but there don't seem to be that many . Zs类中的任何Unicode字符都是JavaScript中的空白字符但似乎没有那么多

However, JavaScript also allows Unicode characters in identifiers , which lets you use interesting variable names like ಠ_ಠ . 但是, JavaScript还允许在标识符中使用Unicode字符 ,这使您可以使用有趣的变量名称,如ಠ_ಠ


#3楼

I guess it has to do something with the fact that for some strange reason it classifies as whitespace: 我想它必须做一些事情,因为一些奇怪的原因它被归类为空格:

$ 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)

#4楼

It appears that the character that you are using is actually longer than what the actual minus sign (a hyphen) is. 看来您使用的角色实际上比实际减号(连字符)更长。

 
-

The top is what you are using, the bottom is what the minus sign should be. 顶部是您正在使用的,底部是减号应该是什么。 You do seem to know that already, so now let's see why Javascript does this. 你似乎已经知道了,所以现在让我们看看为什么Javascript会这样做。

The character that you use is actually the ogham space mark which is a whitespace character, so it is basically interpreted as the same thing as a space, which means that your statement looks like alert(2+ 40) to Javascript. 您使用的字符实际上是ogham空格标记 ,它是一个空白字符,因此它基本上被解释为与空格相同的东西,这意味着您的语句看起来像Javascript的alert(2+ 40)

There are other characters like this in Javascript. 在Javascript中还有其他类似的字符。 You can see a full list here on Wikipedia . 您可以在维基百科上看到完整列表。


Something interesting I noticed about this character is the way that Google Chrome (and possible other browsers) interprets it in the top bar of the page. 我注意到这个角色的有趣之处在于Google Chrome(以及可能的其他浏览器)在页面顶部栏中解释它的方式。

在此输入图像描述

It is a block with 1680 inside of it. 它内部有1680块。 That is actually the unicode number for the ogham space mark. 这实际上是ogham空间标记的unicode数字。 It appears to be just my machine doing this, but it is a strange thing. 它似乎只是我的机器这样做,但这是一个奇怪的事情。


I decided to try this out in other languages to see what happens and these are the results that I got. 我决定用其他语言尝试一下,看看会发生什么,这些都是我得到的结果。


Languages it doesn't work in: 语言不起作用:

Python 2 & 3 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 (inside the main method) Javamain方法内)

>> 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 PHP

>> 2+ 40;
Use of undefined constant  40 - assumed ' 40' :1

C 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 5

>> perl -e'2+ 40'                                                                                                                                   
Unrecognized character \xE1; marked by <-- HERE after 2+<-- HERE near column 3 at -e line 1.

Languages it does work in: 它的语言有效:

Scheme 方案

>> (+ 2  40)
=> 42

C# (inside the Main() method) C# (在Main()方法内)

Console.WriteLine(2+ 40);

Output: 42

Perl 6 Perl 6

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

#5楼

After reading the other answers, I wrote a simple script to find all Unicode characters in the range U+0000–U+FFFF that behave like white spaces. 在阅读完其他答案后,我写了一个简单的脚本来查找U + 0000-U + FFFF范围内的所有Unicode字符,其行为类似于空格。 As it seems, there are 26 or 27 of them depending on the browser, with disagreements about U+0085 and U+FFFE. 看起来,有26或27个取决于浏览器,对U + 0085和U + FFFE存在分歧。

Note that most of these characters just look like a regular white space. 请注意,大多数这些字符看起来像一个普通的空白区域。

 function isSpace(ch) { try { return Function('return 2 +' + ch + ' 2')() === 4; } catch(e) { return false; } } for (var i = 0; i <= 0xffff; ++i) { var ch = String.fromCharCode(i); if (isSpace(ch)) { document.body.appendChild(document.createElement('DIV')).textContent = 'U+' + ('000' + i.toString(16).toUpperCase()).slice(-4) + ' "' + ch + '"'; } } 
 div { font-family: monospace; } 


#6楼

I'd also like to know if there are more characters behaving like this. 我还想知道是否有更多的人物表现得像这样。

I seem to remember reading a piece a while back about mischievously replacing semi-colons (U+003B) in someone's code with U+037E which is the Greek question mark. 我似乎记得有一段时间读过一篇关于用U + 037E(希腊问号)恶意替换某人代码中的半冒号(U + 003B)的文章。

They both look the same (to the extent that I believe the Greeks themselves use U+003B) but this article stated that the other one wouldn't work. 它们看起来都一样(我认为希腊人自己使用的是U + 003B),但是这篇文章指出另一个不行。

Some more information on this from Wikipedia is here: https://en.wikipedia.org/wiki/Question_mark#Greek_question_mark 有关维基百科的更多信息,请访问: https//en.wikipedia.org/wiki/Question_mark#Greek_question_mark

And a (closed) question on using this as prank from SO itself. 还有一个(封闭的)关于将其用作SO本身的恶作剧的问题。 Not where I originally read it AFAIR though: JavaScript Prank / Joke 不是我最初读它AFAIR的地方: JavaScript恶作剧/笑话

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值