Których znaków można użyć do nazwania zmiennej JavaScript?
Chcę stworzyć małą „bibliotekę rozszerzeń” dla moich użytkowników nieobsługujących JavaScript w pracy (którzy wydają się być wrażliwi, jeśli chodzi o język). Uwielbiam to, jak jQuery i Prototype używają $
znaku dolara, a ponieważ używam jQuery, szukam innego fajnego jednoznakowego symbolu do użycia.
Zdaję sobie sprawę, że mogłem po prostu przetestować kilka znaków, ale mam nadzieję, że zawęzię listę znaków na początek (być może, biorąc pod uwagę przyszłą integrację z inną popularną biblioteką).
javascript
character
Richard Clayton
źródło
źródło
Odpowiedzi:
Aby zacytować prawidłowe nazwy zmiennych JavaScript , mój artykuł podsumowujący odpowiednie sekcje specyfikacji:
Stworzyłem również narzędzie , które powie ci, czy dowolny wprowadzony ciąg znaków jest prawidłową nazwą zmiennej JavaScript zgodnie z ECMAScript 5.1 i Unicode 6.1:
PS Aby dać wyobrażenie o tym, jak błędna jest odpowiedź Anthony'ego Millsa: jeśli podsumowałbyś wszystkie te reguły w jednym wyrażeniu regularnym tylko dla ASCII dla JavaScript, miałby on 11 236 znaków . Oto on:
źródło
¢
$
)-:
Zgodnie ze specyfikacją ECMAScript w sekcji 7.6 Nazwy identyfikatorów i identyfikatory prawidłowy identyfikator definiuje się jako:
co stwarza wiele możliwości nazywania zmiennych, a także gry w golfa. Spróbujmy kilku przykładów.
Ważny identyfikator można uruchomić albo z
UnicodeLetter
,$
,_
, lub\ UnicodeEscapeSequence
. Litera unicode to dowolny znak z tych kategorii ( zobacz wszystkie kategorie ):Już to wyjaśnia pewne szalone możliwości - przykłady działania . Jeśli nie działa we wszystkich przeglądarkach, nazwij go błędem, bo powinien.
źródło
Zasadniczo, w zwykłej postaci wyrażenie:
[a-zA-Z_$][0-9a-zA-Z_$]*
. Innymi słowy, pierwszym znakiem może być litera lub _ lub $, a pozostałe znaki mogą być literami _ lub $ lub cyframi.Uwaga: Podczas gdy inne odpowiedzi wskazywały, że można używać znaków Unicode w identyfikatorach JavaScript, pytanie brzmiało: „Jakich znaków powinienem użyć w nazwie biblioteki rozszerzeń, takiej jak jQuery?”. To jest odpowiedź na to pytanie. W identyfikatorach można używać znaków Unicode, ale nie rób tego. Kodowania cały czas psują się. Trzymaj swoje publiczne identyfikatory w zakresie 32-126 ASCII, gdzie jest to bezpieczne.
źródło
Console.WriteLine("привет")
C # i sprawić, by faktycznie działał !Przed JavaScript 1.5:
^[a-zA-Z_$][0-9a-zA-Z_$]*$
W języku angielskim: musi zaczynać się od znaku dolara, podkreślenia lub jednej z liter alfabetu 26 znaków, wielkich lub małych liter. Kolejnymi znakami (jeśli występują) może być dowolny z nich lub cyfra dziesiętna.
JavaScript 1.5 i nowsze * :
^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$
Trudniej to wyrazić w języku angielskim, ale jest ona koncepcyjnie podobna do starszej składni z tym, że litery i cyfry mogą pochodzić z dowolnego języka. Po pierwszym znaku dozwolone są również dodatkowe znaki podobne do podkreślenia (zwane łącznie „łącznikami”) i dodatkowe znaki łączące znaki („modyfikatory”). (Inne symbole walut nie są uwzględnione w tym rozszerzonym zestawie).
JavaScript 1.5 i nowsze wersje zezwalają również na sekwencje specjalne Unicode, pod warunkiem, że wynik jest znakiem dozwolonym w powyższym wyrażeniu regularnym.
Identyfikatory również nie mogą być bieżącym zarezerwowanym słowem lub słowem rozważanym do wykorzystania w przyszłości.
Długość identyfikatora nie ma praktycznego ograniczenia. (Przeglądarki różnią się, ale bezpiecznie będziesz mieć 1000 znaków i prawdopodobnie kilka rzędów wielkości więcej niż to.)
Linki do kategorii postaci:
(połączone w wyrażeniu regularnym powyżej jako „L”)
* nb To wyrażenie regularne w Perlu ma opisywać tylko składnię - nie będzie działać w JavaScript, który nie obejmuje (jeszcze) obsługi właściwości Unicode. (Istnieją pakiety innych firm, które twierdzą, że dodają takie wsparcie).
źródło
"test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === null
mimo że „test” jest prawidłową nazwą zmiennej JS\uD87E\uDC00
), Które nie pasują do żadnego z dozwolonych znaków Unicode kategorie. Twoje wyrażenie regularne pozwoliłoby jednak na taką postać. Brakuje również U + 200C i U + 200D.W rzeczywistości ECMAScript mówi na stronie 15: że identyfikator może zaczynać się od $, podkreślenia lub UnicodeLetter, a następnie (dalej poniżej) określa, że UnicodeLetter może być dowolnym znakiem z kategorii Unicode, Lo, Ll , Lu, Lt, Lm i Nl. A kiedy spojrzysz na te kategorie, zobaczysz, że otwiera to o wiele więcej możliwości niż tylko litery łacińskie. Wystarczy wyszukać „google catagories” w Google i można je znaleźć.
źródło
Zmienne JavaScript
Możesz rozpocząć zmienną dowolną literą
$
lub_
znakiem. Tak długo, jak nie zaczyna się od cyfry, możesz także dołączyć liczby.Początek:
[a-z], $, _
Zawierać:
[a-z], [0-9], $, _
jQuery
Możesz użyć
_
swojej biblioteki, aby stała obok siebie z jQuery. Istnieje jednak konfiguracja, którą można ustawić tak, aby jQuery nie używał$
. Zamiast tego użyjejQuery
. Aby to zrobić, po prostu ustaw:Ta strona wyjaśnia, jak to zrobić.
źródło
O ile mi wiadomo, zaakceptowana odpowiedź wykluczałaby wiele ważnych identyfikatorów . Oto wyrażenie regularne, które zestawiłem, które powinno być zgodne ze specyfikacją (patrz rozdział 7.6 na temat identyfikatorów). Utworzono go za pomocą RegexBuddy, a eksport wyjaśnienia można znaleźć na stronie http://samples.geekality.net/js-identifiers .
Ponadto nazwa nie może być jednym z następujących zastrzeżonych słów.
źródło
^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\u200C\u200D]*$
. Teraz nawet z korektą nie wydaje mi się, aby ten regex działał."test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === null
mimo że „test” jest prawidłową nazwą zmiennej JStest
jest również akceptowany.\uD87E\uDC00
), Które nie pasują do żadnego z dozwolonych znaków Unicode kategorie. Twoje wyrażenie regularne pozwoliłoby jednak na taką postać.eval
,arguments
,NaN
,Infinity
iundefined
przypadków brzegowych .Zmienne JavaScript mogą mieć litery, cyfry, znaki dolara ($) i podkreślenia (_). Nie mogą zaczynać się cyframi.
Zwykle biblioteki używają
$
i_
jako skróty do funkcji, których będziesz używać wszędzie. Chociaż nazwy$
lub_
nie są znaczące, są przydatne ze względu na ich skrót i ponieważ będziesz używać tej funkcji wszędzie, gdzie oczekuje się, że wiesz, co one oznaczają.Jeśli twoja biblioteka nie polega na używaniu wszędzie jednej funkcji, radzę użyć bardziej znaczących nazw, ponieważ pomogą one tobie i innym zrozumieć, co robi twój kod, niekoniecznie narażając na szwank jakość kodu źródłowego .
Możesz na przykład rzucić okiem na niesamowitą bibliotekę DateJS i na cukier syntetyczny, na który pozwala bez żadnego symbolu lub zmiennych o krótkiej nazwie .
Najpierw powinieneś uzyskać praktyczny kod i dopiero po jego upiększeniu.
źródło
jeśli wyrażenia regularne nie są koniecznością, czy nie lepiej byłoby po prostu poprosić przeglądarkę, aby zdecydowała się na użycie
eval
?źródło
xss = alert("I'm in your vars executin mah scrip's");;;;;
na przykład nie jest prawidłową nazwą zmiennej javascript.xss;alert("try again");
name
z(typeof name === "string")? name.replace(/\(|\)/,"") : "_noXSS" )
? Jeśli jest to ciąg, zastąpi nawiasy (zdecydowanie nie dozwolone w zmiennych), więc myślę, że wykonanie czegokolwiek byłoby prawie niemożliwe.isValidVarName('aler(t')
staje się prawdą. IisValidVarName('_;;;')
pozostaje prawdą. Ale możesz na początku sprawdzić, czy pasuje do czegoś podobnego,/[;,\(\)]/
ale nadal możesz wykonać,_=location="#!?"
aby dodać=
do listy, ale nadal możesz wykonać'_\ndelete foo'
(który przechodzi test jako prawidłową nazwę zmiennej), więc musisz wykluczyć\n
s i\r
si jakaś nowa linia Unicode? Ale „$” nie jest prawidłowym identyfikatorem, więc musisz wykluczyć wszystkie białe znaki ... To przegrana bitwa. Myślę, że to jest tak daleko, jak mogę przeciwstawić się sobieif(/[;,\(\)=\s]/.exec(name))return!1
Oto jedna szybka sugestia dotycząca tworzenia nazw zmiennych. Jeśli chcesz, aby zmienna nie powodowała konfliktu, gdy jest używana w FireFox, nie używaj nazwy zmiennej „ _content ”, ponieważ ta nazwa zmiennej jest już używana przez przeglądarkę. Odkryłem to na własnej skórze i musiałem zmienić wszystkie miejsca, w których używałem zmiennej „_content” w dużej aplikacji JavaScript.
źródło
Wziąłem pomysł Anasa Nakawy i ulepszyłem go. Po pierwsze, nie ma powodu, aby faktycznie uruchamiać deklarowaną funkcję. Chcemy wiedzieć, czy poprawnie analizuje, a nie czy kod działa. Po drugie, dosłowny obiekt jest lepszym kontekstem dla naszych celów niż
var XXX
trudniej się z niego wyrwać.źródło
isValidVarName('}; }); alert("I\'m in your vars executin\' mah scripts"); true; // yeah, super valid');
}
powinno to wykluczać.isValidVarName("delete") === true
Napisałem obszar roboczy usterki, który iteruje wszystkie punkty kodowe i emituje znak, jeśli
eval('var ' + String.fromCodePoint(#) + ' = 1')
działa.Po prostu idzie dalej i idzie dalej ...
źródło