W Firefoksie 3.5, wpisuję to w konsoli Firebug:JavaScript: {} == false to błąd SyntaxError?
false=={} // => evals to false
{}==false // syntax error
Jakie jest wytłumaczenie tego?
W Firefoksie 3.5, wpisuję to w konsoli Firebug:JavaScript: {} == false to błąd SyntaxError?
false=={} // => evals to false
{}==false // syntax error
Jakie jest wytłumaczenie tego?
{
na początku instrukcji sygnalizuje "blok oświadczenie (zob ECMA-262-3 rozdział 12.1), który zawiera listę wyciągów.
}
natychmiast kończy blok instrukcji bez żadnych instrukcji. W porządku. Ale teraz parser szuka następnej instrukcji:
==false
Huh? To nie jest oświadczenie; błąd składni.
Do czego służą bloki instrukcji?Cóż, piszesz bloku komunikat za każdym razem mówisz:
if (something) {
...
}
JavaScript definiuje te oświadczenia kontroli przepływu jak:
if "(" <expression> ")" <statement> [else <statement>]
tj. w pojedynczym formularzu oświadczenia bez żadnych nawiasów klamrowych. Następnie pozwala używać bloku instrukcji wszędzie, gdzie możesz użyć pojedynczej instrukcji, co oznacza, że możesz mieć -sam-nawiasy-wiele-instrukcji. Ale oznacza to również, że możesz mieć własny blok instrukcji bez żadnego powiązanego oświadczenia kontroli przepływu.
To absolutnie nie ma praktycznego zastosowania! Można ulec pokusie, aby myśleć, że dał ci ukrywania informacji, ale nie:
var a= 1;
{
var a= 2;
}
alert(a);
... Wyniki w 2
, ponieważ oświadczenie nie blokuje w sobie utworzyć nowy zakres.
JavaScript definiuje sterowanie przepływem i bloki instrukcji w ten sposób, ponieważ zrobił to C (i inne języki z niego wyprowadzone). Języki te nie sprawiały jednak, że {}
służyły jako podwójny obowiązek jako dosłowne wyrażenie w Object, więc nie miały one dwuznaczności, która sprawia, że jest to kolejna nieprawidłowość JS.
Nawet to wannabe-dosłowny:
{
a: 1
}
jest ważny blok stwierdzenie, ponieważ „:” jest używany do oznaczenia etykietą w oświadczeniu. (i 1
jest bezużytecznym wyrażeniem-wyrażeniem, z pominięciem średnika.) Etykiety są kolejną cechą odziedziczoną po C, rzadko używaną w JavaScript. Nie są zupełnie bezsensowne jak klocki, ale rzadko są potrzebne i często traktowane w złym guście.
(Dosłowne z dwóch właściwości spowoduje błąd składni, jako literały obiektowe użyciu separatorów przecinek, ale oznakowane oświadczenia muszą być oddzielone średnikiem.)
To not the only place gdzie luźne składnia JavaScript w przeglądarce, może zadziałać cię dokonując inne stwierdzenie czegoś, co uważasz za wyrażenie.
OK, zapoznałem się z ECMAScript specification (PDF) i mam wyjaśnienie, które omawia BNF grammar.
źródła ECMAScript są przetwarzane począwszy od głównego symbolu, zwany Program
:
Program:
SourceElements
SourceElements' (rekurencyjny) określenie to:
SourceElements :
SourceElement
SourceElements SourceElement
La, SourceElement jest zdefiniowany jako:
SourceElement :
Statement
FunctionDeclaration
Co nas interesuje, to literalna składnia obiektu, więc ignorować FunctionDeclaration i spójrz na symbol oświadczenie:
Statement :
Block
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
IterationStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
LabelledStatement
SwitchStatement
ThrowStatement
TryStatement
nie jestem pewien, czy w sprawach porządkowych aukcji (jest to w jaki sposób są one w ciemno), ale ... obiekt dosłowny jest ExpressionStatement, o których normy mówią następujące (rozdział 12.4):
pamiętać, że ExpressionStatement nie można uruchomić z otworem kręcone nawiasów, ponieważ mogłoby uczynić go niejednoznaczne z blokiem. Ponadto wyrażenie ExpressionStatement nie może rozpocząć się od słowa kluczowego funkcji, ponieważ ten może spowodować, że będzie on niejednoznaczny z funkcją FunctionDeclaration .
więc możemy mieć wyraz na początku programu, ale nie musi zaczynać się od otwarcia nawias klamrowy ({
). Dlatego następujące prace OK:
({} == false);
alert({} == false);
!{} == false;
-1 Nie jest prawdziwą odpowiedzią (.. albo po prostu nie rozumiem). Zapraszam do oświecenia mnie :) – roosteronacid
Masz całkowitą rację. To raczej obejście. Przeszukuję specyfikację ECMAScript 3, aby znaleźć prawdziwą odpowiedź. Ja też jestem ciekawy. –
Aye. Usunąłem mój głos w dół. – roosteronacid
Po prostu powiedzieć, {}==false
są kompilowane przez kompilator JS do {};==false
, więc jest błąd składni. powinieneś napisać ({})==false
, a to zwróci false.
Jego JavaScript ... sobie z tym poradzić. –
Interesujące, ale jaki jest dokładnie cel tego? –
hm, 'false == {}' evals to 'false' w moim Firefox 3.5.3 – SilentGhost