Я был озадачен, когда коллега показал мне эту строку с предупреждением JavaScript 42.
alert(2+ 40);
Быстро выясняется, что то, что выглядит как знак минус, на самом деле является загадочным символом Юникода с явно различной семантикой.
Это заставило меня задуматься, почему этот символ не генерирует синтаксическую ошибку при разборе выражения. Я также хотел бы знать, есть ли еще персонажи, ведущие себя так.
javascript
unicode
GOTO 0
источник
источник
;
редактор имеет тенденцию превращать странный символ `` в обычный пробел, но если вы отмените это "автокоррекция", у вас будет такое же поведение , Этот символ имеет ту же семантику, что и пробел, даже если он выглядит как дефис или минус (в обычных шрифтах).Ответы:
Этот персонаж - «OGHAM SPACE MARK» , это космический персонаж. Таким образом, код эквивалентен
alert(2+ 40)
.Любой символ Unicode в классе Zs является символом пробела в JavaScript , но, похоже, их не так много .
Однако JavaScript также позволяет использовать символы Unicode в идентификаторах , что позволяет использовать интересные имена переменных, например
ಠ_ಠ
.источник
Zs
символы считаются пробелами в JavaScript. Есть еще: github.com/mathiasbynens/regexpu/blob/…ಠ_ಠ
можно использовать в качестве идентификатора в JS: ಠ_ಠಠ
трактовать как букву - это просто здравый смысл, так как это буква. Это было бы явной ошибкой, еслиಠ_ಠ
бы ее нельзя было использовать в качестве идентификатора.Прочитав другие ответы, я написал простой скрипт, чтобы найти все символы Юникода в диапазоне U + 0000 – U + FFFF, которые ведут себя как пробелы. Похоже, их 26 или 27, в зависимости от браузера, с разногласиями по поводу U + 0085 и U + FFFE.
Обратите внимание, что большинство этих символов просто выглядят как обычные пробелы.
Показать фрагмент кода
источник
\p{Default Ignorable Code Point}
не просто\p{Noncharacter Code Pount}
. U + 0085 всегда был\p{Whitespace}
кодовой точкой. Злой - монгольский разделитель U + 180E, который «недавно» потерял свою\p{Whitespace}
собственность. Обратите внимание, что\p{Pattern Whitespace}
это гораздо меньший набор и неизменное свойство. Но\p{Whitespace}
это не так.FEFF
является спецификацией и может рассматриваться как «пространство без перерывов нулевой ширины» в текстах.FFFE
это эквивалентный регистр Возможно, именно поэтому некоторые браузеры рассматривают это как пробелы.Похоже, что используемый вами символ на самом деле длиннее, чем фактический знак минуса (дефис).
Верхняя часть - это то, что вы используете, нижняя - это то, каким должен быть знак минус. Вы, кажется, уже знаете это, так что теперь давайте посмотрим, почему Javascript делает это.
Символ, который вы используете, на самом деле является пробелом ogham, который является пробельным символом, поэтому он в основном интерпретируется как то же самое, что и пробел, что означает, что ваше утверждение похоже
alert(2+ 40)
на Javascript.В Javascript есть и другие подобные символы. Вы можете увидеть полный список здесь, в Википедии .
Что-то интересное, что я заметил в этом символе, - это то, как Google Chrome (и, возможно, другие браузеры) интерпретирует его в верхней панели страницы.
Это блок с
1680
внутренней частью. На самом деле это номер Unicode для знака пробела в Ogham. Кажется, это делает моя машина, но это странная вещь.Я решил попробовать это на других языках, чтобы увидеть, что происходит, и вот результаты, которые я получил.
Языки, на которых он не работает:
Python 2 и 3
Рубин
Java (внутри
main
метода)PHP
С
Идти
Perl 5
Языки, на которых он работает:
Схема
C # (внутри
Main()
метода)Perl 6
источник
sudo apt-get install unicode
хотя только после нескольких часов исследований и неудачных попыток)Я думаю, это связано с тем, что по какой-то странной причине он классифицируется как пробел:
источник
unicode
.unicode
Радованом Гарабиком. Соответствующий репозиторий находится по адресу github.com/garabik/unicode .' '.codePointAt(0)
на консоли выдаст 5760. Теперь Google 5760 Unicode.Кажется, я помню, как читал некоторое время назад статью о хитрой замене точек с запятой (U + 003B) в чьем-то коде на U + 037E, что является греческим вопросительным знаком.
Они оба выглядят одинаково (насколько я думаю, сами греки используют U + 003B), но в этой статье говорится, что другая не будет работать.
Еще немного информации об этом из Википедии здесь: https://en.wikipedia.org/wiki/Question_mark#Greek_question_mark
И (закрытый) вопрос об использовании этого как шутка от самого SO. Не там, где я изначально читал это AFAIR, хотя: JavaScript Prank / Joke
источник