Byłem zaskoczony, gdy kolega pokazał mi tę linię JavaScript z ostrzeżeniem 42.
alert(2+ 40);
Szybko okazuje się, że to, co wygląda jak znak minus, jest w rzeczywistości tajemnym znakiem Unicode o wyraźnie innej semantyce.
To mnie zastanawia, dlaczego ten znak nie powoduje błędu składniowego podczas analizowania wyrażenia. Chciałbym również wiedzieć, czy jest więcej takich postaci.
javascript
unicode
GOTO 0
źródło
źródło
;
, edytor ma tendencję do zmiany dziwnej `` postaci na normalną przestrzeń, ale jeśli cofniesz tę „automatyczną korektę”, zachowujesz się tak samo . Ten znak ma taką samą semantykę jak spacja, nawet jeśli wygląda jak łącznik lub minus (w zwykłych czcionkach).Odpowiedzi:
Ta postać to „OGHAM SPACE MARK” , która jest postacią spacji. Więc kod jest równoważny z
alert(2+ 40)
.Dowolny znak Unicode w klasie Zs jest znakiem JavaScript w białej spacji , ale wydaje się , że nie ma go zbyt wiele .
Jednak JavaScript pozwala również na znaki Unicode w identyfikatorach , co pozwala używać interesujących nazw zmiennych, takich jak
ಠ_ಠ
.źródło
Zs
znaki w JavaScript są traktowane jako białe znaki. Jest więcej: github.com/mathiasbynens/regexpu/blob/…ಠ_ಠ
można go użyć jako identyfikatora w JS: ಠ_ಠಠ
traktowanie jak literę jest po prostu zdrowym rozsądkiem, ponieważ jest literą. Byłby to wyraźny błąd, gdybyಠ_ಠ
nie mógł zostać użyty jako identyfikator.Po przeczytaniu innych odpowiedzi napisałem prosty skrypt, aby znaleźć wszystkie znaki Unicode z zakresu U + 0000 – U + FFFF, które zachowują się jak białe znaki. Jak się wydaje, jest ich 26 lub 27, w zależności od przeglądarki, z nieporozumieniami na temat U + 0085 i U + FFFE.
Zauważ, że większość z tych postaci wygląda jak zwykła biała spacja.
Pokaż fragment kodu
źródło
\p{Default Ignorable Code Point}
nie tylko\p{Noncharacter Code Pount}
. U + 0085 zawsze był\p{Whitespace}
kodem. Zły to U + 180E MONGOLIJSKI SEPARATOR GŁÓWNY, który „niedawno” utracił swoją\p{Whitespace}
własność. Zauważ, że\p{Pattern Whitespace}
jest to znacznie mniejszy zestaw i niezmienna właściwość. Ale\p{Whitespace}
nie jest.FEFF
jest BOM i może być traktowany jak „przestrzeń zerowa o zerowej szerokości” w tekstach.FFFE
jest to ekwiwalent zamiany Endian. Być może dlatego niektóre przeglądarki traktują to jako białe znaki.Wygląda na to, że znak, którego używasz, jest w rzeczywistości dłuższy niż rzeczywisty znak minus (łącznik).
Góra jest tym, czego używasz, dół to znak minus. Wydaje się, że już to wiesz, więc teraz zobaczmy, dlaczego JavaScript to robi.
Znak, którego używasz, jest tak naprawdę znakiem spacji ogham, który jest znakiem spacji, więc jest zasadniczo interpretowany jako to samo co spacja, co oznacza, że twoje wyrażenie wygląda jak
alert(2+ 40)
JavaScript.Istnieją inne takie znaki w Javascript. Możesz zobaczyć pełną listę tutaj na Wikipedii .
Coś interesującego, co zauważyłem w tej postaci, to sposób, w jaki Google Chrome (i możliwe inne przeglądarki) interpretuje ją na górnym pasku strony.
To jest blok z jego
1680
wnętrzem. Jest to w rzeczywistości numer Unicode znaku spacji oghama. Wygląda na to, że robi to tylko moja maszyna, ale to dziwna rzecz.Postanowiłem wypróbować to w innych językach, aby zobaczyć, co się stanie i takie są wyniki, które uzyskałem.
Języki, w których nie działa:
Python 2 i 3
Rubin
Java (wewnątrz
main
metody)PHP
do
Udać się
Perl 5
Języki, w których działa:
Schemat
C # (wewnątrz
Main()
metody)Perl 6
źródło
sudo apt-get install unicode
chociaż dopiero po wielu godzinach badań i nieudanych próbach)Wydaje mi się, że ma to coś wspólnego z tym, że z jakiegoś dziwnego powodu klasyfikuje się go jako biały znak:
źródło
unicode
.unicode
autorstwa Radovana Garabíka. Odpowiednie repo znajduje się na stronie github.com/garabik/unicode .' '.codePointAt(0)
na konsoli da 5760. teraz google 5760 Unicode.Wydaje mi się, że pamiętam jakiś czas temu o złośliwym zastępowaniu średników (U + 003B) w czyimś kodzie U + 037E, który jest greckim znakiem zapytania.
Oba wyglądają tak samo (do tego stopnia, że uważam, że sami Grecy używają U + 003B), ale w tym artykule stwierdzono, że drugi nie zadziała.
Więcej informacji na ten temat z Wikipedii znajduje się tutaj: https://en.wikipedia.org/wiki/Question_mark#Greek_question_mark
I (zamknięte) pytanie dotyczące używania tego jako dowcipu z samego SO. Ale nie tam, gdzie go pierwotnie przeczytałem AFAIR: JavaScript Prank / Joke
źródło