2015-10-21 13 views
5

Wiem, że let ma zadeklarować lokalne zmienne zakresu bloków, ale dlaczego nie obsługuje redeclaracji i podnoszenia, jak robi to var?Dlaczego zezwolić, aby instrukcja zachowywała się tak bardzo od var?

Jaki jest cel konstrukcyjny tego ograniczenia?

(function(){ 
    'use strict'; 
    alert(a);  // undefined 
    var a; 
})(); 

(function(){ 
    'use strict'; 
    alert(a);  // error 
    let a; 
})(); 

(function(){ 
    'use strict'; 
    var a; 
    var a; 
    alert(a);  // undefined 
})(); 

(function(){ 
    'use strict'; 
    let a; 
    let a;   // error 
    alert(a); 
})(); 
+1

@ user2190986, ale jasne jest, że 'let' nie deklaruje stałych w JavaScript – Rufus

+0

@ user2190986' const' służy do deklarowania stałych. – Alastair

+1

'let' deklaracje ** są ** podniesione. Ale w przeciwieństwie do deklaracji 'var', zmienna nie jest inicjowana za pomocą' undefined' na początku bloku. – zeroflagL

Odpowiedz

8

Chodzi o to, aby stworzyć narzędzie, które jest bardziej jednoznaczna i bardziej rygorystyczne niż oryginalny var.

Jako człowiek, po to ważny JavaScript, ale prawie niemożliwe do zrozumienia:

alert(a); // Where does a come from? Why does this not throw? 
/* 1000 lines later, or even in an entirely different file */ 
var a; 

Ponadto wyobrazić kodu z 5 var deklaracji do tej samej zmiennej w tym samym zakresie, niektóre w if sprawozdania, niektóre w for s. Który jest pierwszy? Jaka wartość zostanie utworzona?

Pomysł polegał na naprawieniu niektórych z bad parts of var.

1

Ten sam powód, dla którego dowolny operator jest wyświetlany w dowolnym języku programowania - w celu ograniczenia liczby sposobów strzelania sobie w stopę. Old-school Javascript jest po prostu pełen tych.

Zauważ, że możesz użyć let dla zakresu bloku lokalny:

while (i < 5) 
{ 
    let a = 42; 

    i++; 
} 

Nawet pętla biegnie kilka razy, a jest zawsze inicjowana prawidłowo.

Co się stanie, jeśli masz inną zmienną w wyższym zakresie?

let a = 42; 

while (i < 5) 
{ 
    let a = 10; 

    // What is the value of a here? 
    i++; 
} 

// And here? 

Jest tu pewien poziom niejednoznaczności - a niejednoznaczność jest złą cechą w języku programowania. Nie stanowi to problemu z zakresem var bez blokowania - że ma mnóstwo własnych problemów i ludzie nadużywają go przez cały czas, ale przynajmniej jest oczywiste, że zakres blokowy jest określony jako var. I nawet wtedy - ludzie używają go tak, jakby był on blokowany.

Jedynym sposobem na naprawienie tego szaleństwa jest uczynienie języka nieco bardziej rygorystycznym. Czy to faktycznie oznacza, że ​​straciłeś jakąś funkcję? Nie. Zmienne zacienianie było złym pomysłem z var, i nadal byłby to zły pomysł z let (i jak pokazuje mój przykład, być może gorszy).

Nie dotyczy to wyłącznie JavaScriptu, a nie długiego ujęcia. Na przykład w języku C#:

int i = 0; 

int i = 42; // Compiler error: A local variable named 'i' is already defined in this scope 

Dlaczego? Ponieważ masz , oczywiście popełniono błąd. Być może skopiowałeś fragment kodu z innego miejsca i nie zauważyłeś, że masz już zadeklarowaną inną zmienną o nazwie i. Być może zapomniałeś, że jesteś w środku innej pętli, która również używa i jako zmiennej pętli. Nie ma prawdziwego uzasadnionego użycia, a mimo to jest mnóstwo trybów awarii - to po prostu okropna funkcja językowa.Prosty błąd kompilatora zapobiega występowaniu prawie wszystkich tych awarii - a wiele z tych awarii może być bardzo trudnych do znalezienia, szczególnie jeśli blok "wewnętrzny" nie jest używany zbyt często.

Powiązane problemy