Почему транспилятор машинописного текста не поднимает переменные?

Я понимаю, что ES6 и TypeScript поддерживают область видимости на уровне блоков, но при нацеливании на ES3 и ES5 вывод должен быть областью видимости на функциональном уровне. Я думаю, что должна быть логика, почему TypeScript не поднимает переменные... и я не сталкиваюсь с проблемой, мне просто любопытно, почему он не поднимает переменные.

Например, учитывая следующий TypeScript:

function seed(length: number, multiplier: number): number[] {
  let result: number[] = [];

  for(let i: number = 0; i < length; i++) {
    let n: number = i * multiplier;

    result.push(n);
  }

  return result;
}

Транспилятор выдает:

function seed(length, multiplier) {
  var result = [];
  for (var i = 0; i < length; i++) {
    var n = i * multiplier;
    result.push(n);
  }
  return result;
}

Я ожидал, что в результате объявления переменных будут подняты в начало функции. Выглядит примерно так:

function seed(length, multiplier) {
  var
    i, n,
    result = [];

  for (i = 0; i < length; i++) {
    n = i * multiplier;
    result.push(n);
  }
  return result;
}

Любое понимание очень ценится. Спасибо!


person roto    schedule 12.05.2016    source источник


Ответы (2)


Это потому, что компилятор не выводит код на основе стандарта кодирования. Он пытается быть как можно ближе к исходному вводу.

Обратите внимание, что var переменные в любом случае поднимаются за кулисами (var hoisting). В этом случае компилятору TypeScript не нужно изменять входные данные, и это без необходимости увеличивает его сложность.

person David Sherret    schedule 12.05.2016

Я думаю, что должна быть логика, почему TypeScript не поднимает переменные... и я не сталкиваюсь с проблемой, мне просто любопытно, почему он не поднимает переменные.

Именно это. Поскольку это не проблема, зачем идти на подъем?

Также в случае let было бы неправильно поднимать его так, как вы показали.

Временная мертвая зона

Во-первых, переменные let нельзя использовать до объявления, как могут быть переменные var. С var вы получите undefined. С let вы получите ReferenceError из-за временной мертвой зоны. К счастью, TypeScript все равно выдаст вам ошибку времени компиляции, поэтому вы не столкнетесь с ней во время выполнения:

console.log(a); // Error: Block scoped variable used before declaration 
let a = 123;

Область видимости блока

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

Опять же, TypeScript выдаст вам ошибку времени компиляции, если вы неправильно используете let (вместо того, чтобы столкнуться с ним во время выполнения):

for(let i: number = 0; i < 10; i++) {    
}  
console.log(i); // Error: no variable i in scope

Надеюсь, это поможет ????

person basarat    schedule 13.05.2016
comment
Но вывод для ES3/5 использовал let, а не var. Таким образом, он может переместить объявление наверх. Но нет особого смысла делать это в автоматически сгенерированном коде, который уже проверен на правильность. - person Daniel Earwicker; 13.05.2016