2009-08-05 12 views
49

Używam JSLint, aby poczuć się źle z powodu mojego JavaScript. Przy okazji jest super. Jest jedna kontrola, której nie bardzo rozumiem i proszę o twoje opinie.Jeden var na funkcję w JavaScript?

Od jslint.com:

W językach z zakresu bloku, zaleca się zwykle, że zmienne być zadeklarowane w miejscu pierwszego użycia. Ale ponieważ JavaScript nie ma zasięgu bloku, rozsądniej jest zadeklarować wszystkie zmienne funkcji u góry funkcji. Zaleca się stosowanie pojedynczej instrukcji var dla każdej funkcji.

Co tak naprawdę brzmi ostatnie słowo pogrubione? Myślę, że powinienem zadeklarować wiele zmiennych w ten sposób?

var foo = 1, bar = 2; 

A jest „mądry” część po prostu styl programowania, aby zniechęcić błędów w dół linii lub jest tam więcej niż tylko to?

Dzięki za pomoc.

+0

Otrzymałem dwie doskonałe odpowiedzi od http://stackoverflow.com/users/5445/cms i http://stackoverflow.com/users/51101/breton. Czuję, że razem oboje odpowiadają na to pytanie. Jak mogę dać kredyt obu? :( –

+7

Przy okazji, jeśli naprawdę chcesz źle się czuć na swoim kodzie, spróbuj odczytać kod źródłowy do JSLINT i dowiedzieć się, jak to działa.To jest idealnie proste i czytelne, a jednak wciąż tajemnicze.To jak odkrywanie, że wszechświat jest fraktala obliczonego przez równanie 2 + 2 =? – Breton

+0

Czy ktoś nie narzędzia, które automatycznie przeformatuje kod do jednego var na styl funkcji? (ale nie minify) – jlarson

Odpowiedz

71

Problem polega na tym, że javascript niewidzialnie przenosi wszystkie deklaracje var na szczyt zakresu funkcji.

więc jeśli masz funkcję jak ten

var i = 5; 
function testvar() { 
    alert(i); 
    var i=3; 
} 
testvar(); 

oknie alertu będzie zawierać niezdefiniowane. ponieważ wewnętrznie zostało to zmienione na:

var i = 5; 
function testvar() { 
    var i; 
    alert(i); 
    i=3; 
} 
testvar(); 

to się nazywa "podnoszenie". Powodem, dla którego Crockford tak zdecydowanie popiera deklaracje w var, jest to, że kod ten w widoczny sposób odpowiada temu, co zamierza zrobić, zamiast pozwalać na wystąpienie niewidocznego i nieoczekiwanego zachowania.

+0

Interesujące - nigdy tak naprawdę nie wiedziałem o JS - oczywiście, zazwyczaj definiuję wszystkie moje zmienne na górze i rzadko ponownie używam nazwy zmiennej z zewnętrznej pętli/funkcji. – gnarf

+0

Jest to interesujące, ale nie tak naprawdę związane z zakresem bloku. – Triptych

+0

Ale jest to poprawna odpowiedź na moje pytanie ... –

8

Zasadniczo w blokach JavaScript ({ ... }) nie wprowadzaj nowego zakresu, istnieje tylko zakres funkcji, więc żaden zakres nie jest tworzony na żadnej innej instrukcji.

Zmienna wprowadzona w dowolnym miejscu funkcji jest widoczna wszędzie w funkcji.

Na przykład:

function myFunction(){ 
    var one = 1; 

    if (one){ 
    var two = one + 1; 
    } 

    (function() { 
    var three = one + two; 
    })(); 

    // at this point both variables *one* and *two* are accessible but 
    // the variable *three* was declared in the scope of a inner function 
    // and is not accessible at this point. 
} 

W językach z zakresu bloku, zaleca się deklarować zmienne w momencie pierwszego użycia, ale ponieważ JavaScript nie posiada zakresu bloku, to lepiej zadeklarować aż tu zmienne funkcji na górze funkcji.

Sprawdź to article.

+2

Naprawdę nie wyjaśniasz, dlaczego jest to lepsze, ale ostatecznie wynika to z zakresu funkcji lepiej jest, aby vars były na górze, ale pominąłeś uzasadnienie od tego faktu do twojego wniosku – Breton

+3

Właśnie przeczytałem artykuł, z którym się łączyłeś i popełnia ten sam błąd co Chetan. redeclaring a var to NOOP. Jest całkowicie łagodny i nie powoduje żadnych problemów. To nie znaczy, że ograniczenie się do jednego oświadczenia var jest bezużyteczne, ale ty, ani ten artykuł, nie zrobiłeś dla niego przekonującego argumentu. – Breton

+0

@Breton, może powodować problemy, ponieważ często jest odbiciem zdezorientowanego programisty. Może także mylić innych programistów, którzy robią to, co sensowne, i umieścić wszystkie vary na szczycie funkcji. – Nosredna

4

Tak, oznacza to, że deklarujesz wszystkie zmienne na początku funkcji. Czy chcesz to zrobić w jednym wierszu, czy w wielu liniach, to kwestia wyboru.

Powód jest wyjaśniony w akapicie, o którym wspomniałeś. Zmienne JavaScript mają tylko zasięg na poziomie funkcji. Jeśli zadeklarujesz tę samą zmienną w bloku if/while/for, zostanie ona nadpisana przez nową wartość, ponieważ blok nie zawiera nowego zakresu. Różni się to od języków takich jak Java. Aby uniknąć takich niespodzianek, zadeklaruj wszystkie zmienne, których będziesz używał w funkcji na początku funkcji, aby nie przypadkowo "redeclare" i cokolwiek.

+0

Nie sądzę, że problemem jest redeclaring a variable. To nie powoduje błędu, jak w C (lub java?). W rzeczywistości nic nie robi. – Breton

+0

Przepraszam, musiałem być bardziej przejrzysty. Chodziło mi o zadeklarowanie tej samej nazwy zmiennej wewnątrz bloku, co jest dozwolone w Javie. Ta nowa zmienna żyje tylko wewnątrz bloku. –

+0

Ach tak, przypuszczam, że byłby to problem, gdybyś był przyzwyczajony do języka z zakresem bloku. – Breton

6

brak zakresu bloku wyjaśnia poniższy kod:

var a = 1; 
if (something) { 
    var a = 2; 
} 

alert(a); // Alerts "2" 

W większości stylu C (jak w składni) językach, definicja var a = 2 byłoby określenie „a” tylko dla zakresu bloku if. Używanie pojedynczej instrukcji var u góry funkcji pomaga uniknąć tego dziwactwa JavaScript, które nie zawsze jest tak oczywiste, jak powyższe, i byłoby nieoczekiwane dla programistów C/C#/Java.

Powiązane problemy