Пусть & amp; Var различный выход [дубликат]

Основное различие - разность областей, в то время как let может быть доступна только в пределах области, которую она объявила, например, для цикла for, например, для доступа к var вне цикла. Из документации в MDN (примеры также из MDN):

let позволяет вам объявлять переменные, которые ограничены по объему блоку, выражению или выражению, на которых Это использовано. Это не похоже на ключевое слово var, которое определяет переменную глобально или локально для целой функции независимо от области блока.

Переменные, объявленные let, имеют в качестве области действия блок, в котором они определены, а также в любых содержащихся подблоках. Таким образом, пусть работает очень похоже на var. Основное различие заключается в том, что область действия переменной var является всей охватывающей функцией:

blockquote>
function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}`

На верхнем уровне программ и функций пусть, в отличие от var, не создать свойство на глобальном объекте. Например:

blockquote>
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined

При использовании внутри блока, ограничивает область видимости переменной этим блоком. Обратите внимание на разницу между var, область видимости которой находится внутри функции, где она объявлена.

blockquote>
var a = 1;
var b = 2;

if (a === 1) {
  var a = 11; // the scope is global
  let b = 22; // the scope is inside the if-block

  console.log(a);  // 11
  console.log(b);  // 22
} 

console.log(a); // 11
console.log(b); // 2

Также не забывайте, что это функция ECMA6, поэтому она еще не полностью поддерживается, поэтому лучше всегда транслирует его в ECMA5 с помощью Babel и т. д. ... для получения дополнительной информации о посещении веб-сайта babel

21
задан Explosion Pills 17 June 2015 в 19:36
поделиться

3 ответа

Является ли это просто синтаксическим сахаром для ES6?

Нет, это больше, чем синтаксический сахар.

.

Как это работает?

Если вы используете это ключевое слово let в инструкции for, он проверит, какие имена он связывает, а затем

  • создает новую лексическую среду с этими именами для a) выражение инициализатора b) каждая итерация (ранее для оценки выражения инкремента)
  • копирует значения из всех переменных с этими именами из одной в следующую среду

Ваш оператор цикла for (var i = 0; i < 10; i++) { process.nextTick(_ => console.log(i)) } desugars на простой

// omitting braces when they don't introduce a block
var i;
i = 0;
if (i < 10)
    process.nextTick(_ => console.log(i))
    i++;
    if (i < 10)
        process.nextTick(_ => console.log(i))
        i++;
        …

, в то время как for (let i = 0; i < 10; i++) { process.nextTick(_ => console.log(i)) } делает «desugar» более сложным

// using braces to explicitly denote block scopes,
// using indentation for control flow
{ let i;
  i = 0;
  __status = {i};
}
{ let {i} = __status;
  if (i < 10)
      process.nextTick(_ => console.log(i))
      __status = {i};
}   { let {i} = __status;
      i++;
      if (i < 10)
          process.nextTick(_ => console.log(i))
          __status = {i};
    }   { let {i} = __status;
          i++;
          …
29
ответ дан Bergi 4 September 2018 в 08:17
поделиться
3
ответ дан Carles Alcolea 4 September 2018 в 08:17
поделиться

let вводит определение области и эквивалентную привязку, так же как функции создают область с закрытием. Я считаю, что соответствующий раздел спецификации 13.2.1 , где в заметке упоминается, что let объявления являются частью LexicalBinding и оба живут в пределах Лексической среды. Раздел 13.2.2 утверждает, что объявления var прикреплены к переменной VariableEnvironment, а не к LexicalBinding.

Объяснение MDN также поддерживает это, заявив, что:

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

, предполагая, что переменные связаны с блок, который меняет каждую итерацию, требующую нового LexicalBinding (я считаю, а не 100% на эту точку), а не окружающая лексическая среда или переменная среда, которая была бы постоянной на время вызова.

Короче , при использовании let замыкание находится в теле цикла, и переменная различается каждый раз, поэтому его необходимо снова захватить. При использовании var переменная находится в окружающей функции, поэтому нет необходимости повторно закрывать, и одна и та же ссылка передается на каждую итерацию.

Адаптация вашего примера для запуска в браузере:

// prints '10' 10 times
for (var i = 0; i < 10; i++) {
  setTimeout(_ => console.log('var', i), 0);
}

// prints '0' through '9'
for (let i = 0; i < 10; i++) {
  setTimeout(_ => console.log('let', i), 0);
}

, безусловно, показывает, что последние печатают каждое значение. Если вы посмотрите на то, как Вавилон перебирает это, он производит:

for (var i = 0; i < 10; i++) {
  setTimeout(function(_) {
    return console.log(i);
  }, 0);
}

var _loop = function(_i) {
  setTimeout(function(_) {
    return console.log(_i);
  }, 0);
};

// prints '0' through '9'
for (var _i = 0; _i < 10; _i++) {
  _loop(_i);
}

Предполагая, что Вавилон довольно совместим, что соответствует моей интерпретации спецификация

5
ответ дан ssube 4 September 2018 в 08:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: