Я был сбит с толку, когда коллега показал мне эту строку оповещения для JavaScript 42.
alert(2+ 40);
Я был сбит с толку, когда коллега показал мне эту строку оповещения для JavaScript 42.
alert(2+ 40);
Этот символ "OGHAM SPACE MARK" , который является символом пробела. Таким образом, код эквивалентен alert(2+ 40)
.
Я также хотел бы знать, есть ли больше персонажей, которые ведут себя так.
Любой символ Юникода в классе Zs является символом пробела в JavaScript, но, похоже, что многие.
Однако JavaScript также позволяет использовать символы Unicode в идентификаторах, что позволяет использовать интересные имена переменных, например ಠ_ಠ
.
Прочитав другие ответы, я написал простой script, чтобы найти все символы Unicode в диапазоне U + 0000-U + FFFF, которые ведут себя как белые пробелы. Как кажется, в зависимости от браузера есть 26 или 27, с разногласиями относительно U + 0085 и U + FFFE.
Обратите внимание, что большинство этих символов просто выглядят как обычное пустое пространство.
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; }
Похоже, что персонаж, который вы используете, на самом деле больше, чем фактический знак минус (дефис).
-
Верх - это то, что вы используете, нижняя часть - знак минуса. Вы, кажется, уже знаете это, поэтому теперь давайте посмотрим, почему Javascript делает это.
Символ, который вы используете, на самом деле является ogham space mark, который является символом пробела, поэтому он в основном интерпретируется как то же, что и space, что означает, что ваше утверждение выглядит как alert(2+ 40)
для Javascript.
В Javascript есть другие символы, подобные этому. Вы можете увидеть полный список здесь, в Википедии.
Что-то интересное, которое я заметил об этом персонаже, - это то, как Google Chrome (и возможные другие браузеры) интерпретирует его в верхней строке страницы.
Это блок с 1680
внутри него. Это фактически номер юникода для метки ogham space. Кажется, это только моя машина делает это, но это странно.
Я решил попробовать это на других языках, чтобы узнать, что происходит, и это те результаты, которые я получил.
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 (внутри метода main
)
>> 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
С
>> 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
С#
(внутри метода Main()
)
Console.WriteLine(2+ 40);
Output: 42
Perl 6
>> ./perl6 -e'say 2+ 40'
42
Я предполагаю, что он должен что-то сделать с тем, что по какой-то странной причине он классифицируется как пробел:
$ 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)
Я также хотел бы знать, есть ли больше персонажей, которые ведут себя так.
Кажется, я помню, как некоторое время читал кусочек о том, чтобы озорно заменить полуколоны (U + 003B) в чей-то код с U + 037E, который является греческим вопросительным знаком.
Оба они выглядят одинаково (в той мере, в какой я считаю, что сами греки используют U + 003B), но в этой статье говорится, что другой не будет работать.
Дополнительная информация об этом из Википедии находится здесь: https://en.wikipedia.org/wiki/Question_mark#Greek_question_mark
И (закрытый) вопрос об использовании этого как шалости от самой SO. Не там, где я изначально читал его AFAIR, хотя: JavaScript Prank/Joke