2015-10-21 5 views
5

Я знаю, что let - объявлять локальные переменные области блока, но почему он не поддерживает повторную декларацию и подъем, например var?Зачем нужно, чтобы оператор вел себя так сильно, как var?

Какова цель этого ограничения?

(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, но ясно, что 'let' не объявляет константы в JavaScript – Rufus

+0

@ user2190986' const' используется для объявления констант. – Alastair

+1

'let' декларации ** ** подняты. Но в отличие от 'var' деклараций переменная не инициализируется с' undefined' в начале блока. – zeroflagL

ответ

8

Идея заключается в том, чтобы создать инструмент, который более однозначными и более строгое, чем оригинальный var.

Как человек, справедливо следующее JavaScript, но почти невозможно понять:

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

Кроме того, представьте себе код с 5 var деклараций по одной и той же переменной в той же области, некоторые в if заявления, некоторые for s. Что является первым? Какая ценность будет создана?

Идея состояла в том, чтобы исправить некоторые из bad parts of var.

1

По той же причине, что любой строгий оператор появляется на любом языке программирования - чтобы ограничить количество способов, которыми вы можете стрелять в ногу. Старая школа Javascript просто переполнена этими.

Обратите внимание, что вы можете использовать let для блока локальной области видимости:

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

    i++; 
} 

Даже если цикл выполняется несколько раз, a всегда правильно инициализированы.

Теперь, что произойдет, если у вас есть другая переменная в более высоком пространстве?

let a = 42; 

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

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

// And here? 

Там есть определенный уровень неопределенности здесь - и неоднозначность плохая особенность в языке программирования. Это не проблема с неблокированным var - у этого есть тонны собственных проблем, и люди злоупотребляют им все время, но по крайней мере очевидно, что var - это never block-scoped. И даже тогда - люди действительно используют его, как будто это были блок-областью.

Единственный способ исправить это безумие - сделать язык немного более строгим. Это на самом деле означает, что вы потеряли какую-либо особенность? Нет. Переменная затенение была плохой идеей с var, и это все равно будет плохой идеей с let (и, как показывает мой пример, возможно, хуже).

Это не уникально для Javascript, а не длинным выстрелом. Например, в C#:

int i = 0; 

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

Почему? Потому что у вас очевидно совершил ошибку. Возможно, вы скопировали фрагмент кода из другого места и не заметили, что у вас уже есть другая переменная с именем i. Возможно, вы забыли, что находитесь в середине другого цикла, который также использует i как переменную цикла. Нет никакого законного использования, и все же есть тонны отказов - это просто ужасная особенность языка.Простая ошибка компилятора предотвращает почти все эти сбои - и многие из этих сбоев могут быть очень трудно найти, особенно если «внутренний» блок используется слишком часто.

Смежные вопросы