8

Javascript, po uruchomieniu JSLint krzyczy na mnie i nie jestem pewien dlaczego.JSLint narzeka na mój spróbuj/złap się

/*jslint browser: true, devel: true, evil: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, newcap: true, immed: true */ 

var foo = function() { 
    try { 
    console.log('foo'); 
    } catch(e) { 
    alert(e); 
    } 

    try { 
    console.log('bar'); 
    } catch(e) { 
    alert(e); 
    } 
}; 

foo(); 

Mówi mi:

Problem na linii 12 znaków 11: 'e' jest już zdefiniowany.

} catch(e) {

Wydaje się być zdenerwowany, że mam drugą catch(e). Dlaczego miałby to być problem? Czy nie ustawia się e zmiennej lokalnej na blok catch? Czy muszę jednoznacznie nazwać zmienne lokalne dla wszystkich wychwyconych błędów w funkcji?

Odpowiedz

9

Do JSLint, try..catch ma niejawny efekt deklarowania e jako zmiennej lokalnej. Ponieważ masz dwa takie bloki w obrębie tej samej funkcji (w JavaScript nie ma żadnego zakresu bloków), JSLint widzi, że jako zadeklarowano zmienną, która została już zadeklarowana jako.

Nazewnictwo zmiennych e1, e2, itp. uniemożliwiłoby to ostrzeżenie od JSLint. Czy to naprawdę problem? Specyfikacja ECMAScript 5, rozdział 12.14, mówi: "Bez względu na to, w jaki sposób kontrola opuszcza Blok, środowisko LexicalEnvironment jest zawsze przywracane do poprzedniego stanu." To w rzeczywistości wydaje się być w przypadku:

try { 
    throw new Error("testing 1234"); 
} catch(fooBarBaz){ 
    alert("Catch: " + fooBarBaz); // works 
} 

alert(fooBarBaz); // throws exception 

Tak więc, aby stwierdzić, jest to po prostu ograniczenie JSLint i jest mało prawdopodobne, aby doprowadzić do praktycznego problemu.

+0

Wygląda na to, że masz rację. Domyślam się, że try/catch nie _nie wprowadzają zakresu, o czym świadczy ten szybki test, który napisałem: http://jsfiddle.net/VRcwV/ –

+0

Och właśnie zobaczyłem edycję! Nie wprowadza więc zakresu, ale zmienna lokalna utworzona przez instrukcję catch nie jest dostępna poza tym haczykiem. Czy wprowadzono niewielki zakres specjalistycznego zakresu tylko dla tego wyjątku? –

+1

@Squeegy: IE 8 jest * niezgodny *, wydaje się. Wypróbuj mój test (http://jsfiddle.net/DpHMt/) w tej przeglądarce, a zobaczysz * oba * pola alertów otwarte. – PleaseStand

0

Urządzenie JSLint I use nie pokazuje żadnego błędu - i logiczne, że kod jest poprawny.

0

Spróbuj użyć innej zmiennej, może się mylić, ponieważ e jest zwykle zarezerwowane dla programów obsługi zdarzeń.

+0

o tyle, o ile wiem, że "e" nie jest zastrzeżone. – pex

0

JSLint może po prostu nie być w tym miejscu. Zgodnie ze specyfikacją ECMAScript wprowadzanie bloku catch tworzy nowy zakres, w którym definiowana jest zmienna wyjątku. W twoim przykładzie wartość e jest poprawna tylko w bloku catch i nie jest zdefiniowana na zewnątrz. Nie ma tu żadnej redefinicji.

+1

Specyfikacja ECMAScipt, na pewno. Ale implementacja przeglądarki, najwyraźniej nie: http://jsfiddle.net/VRcwV/ –

+0

@Squeegy: Jest to tylko zmienna wyjątku 'e', która przechodzi do nowego zakresu. Zmienne zadeklarowane przy 'var' są zawsze w zakresie funkcji. Spróbuj 'alert (e)', a zobaczysz, że jest niezdefiniowany poza blokiem 'catch'. – casablanca

Powiązane problemy