0

Везде явно описывается лишь то, что в отличии от var - let/const обладают блочной областью видимости, но столкнулся с такой проблемой, интересно с чем связано:

let App = App || {};

App.init = function() { console.log('Inited'); }

App.init(); // Uncaught ReferenceError: App is not defined (с const то же самое)

var App = App || {};

App.init = function() { console.log('Inited'); }

App.init(); // 'Inited'

MedvedevDev
  • 5,237

2 Answers2

7

Берем и читаем стандарт.

Переменные Let и Const создаются в запущенном контексте и недоступны ровно до тех пор, пока не будут вычислены их значения при присваивании. Если же вычисления нет, то по умолчанию им присваивается undefined.

Переменные Var создаются в контексте и сразу же инициализируются значением undefined, только потом происходит их вычисление.

13.3 Declarations and the Variable Statement

13.3.1 Let and Const Declarations

NOTE let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

13.3.2 Variable Statement

NOTE A var statement declares variables that are scoped to the running execution context’s VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created. Within the scope of any VariableEnvironment a common BindingIdentifier may appear in more than one VariableDeclaration but those declarations collective define only one variable. A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.

Alex Krass
  • 17,744
  • Во, вот так понятнее, что отличие именно в "очередности задания undefined". Но все же + за верный ответ уже отдал, не взыщи, просто плюсану за пояснение. – MedvedevDev Aug 26 '17 at 23:31
  • @MedvedevDev все нормально, я не переживаю по таким поводам и не гонюсь за рейтингом. Главное, что ответ был полезен. – Alex Krass Aug 26 '17 at 23:41
  • @MedvedevDev Плюсану за тебя :) Почему нет – Oleg Aug 27 '17 at 01:37
  • @Grundy, перелогиньтесь! –  Sep 02 '17 at 03:20
3

Во втором случае App инициализирован и имеет undefined, а в первом случае у тебя ошибка в первой строке о неинициализированной переменной.

  • Это весь js который имеется. – MedvedevDev Aug 26 '17 at 23:01
  • 1
    Перед тем как выполнить код, js движок проходится и инициализирует переменные которые объявлены через var и проставляет им значение undefined. – Паша Иванов Aug 26 '17 at 23:03
  • То есть получается let и var отличаются не только зоной видимости, но и тем как работают (видимо var ищет присвоенные переменные и если не нашел, то задает undefined; а let просто ищет, но ничего не задает)? .... интересное кино. – MedvedevDev Aug 26 '17 at 23:10
  • Подводных камней в js очень много, поэтому лучше почитать соответствующую литературу. – Паша Иванов Aug 26 '17 at 23:12
  • https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/let https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/var Вот документация по var и let – Паша Иванов Aug 26 '17 at 23:14
  • Сколько читал информацию про let, везде говорится лишь про то, что обладает блочной видимостью, просто такие нюансы как-то нигде не видывал (ну или неверно интепретировал информацию), по этому и решил задать вопрос, а не просто оставить var. В этих статьях ничего похожего тоже не наблюдаю. Так же речь только про блочную область видимости. – MedvedevDev Aug 26 '17 at 23:15
  • Цитата:"Объявление переменной всегда обрабатывается до выполнения кода, где бы она ни находилась. " это по var – Паша Иванов Aug 26 '17 at 23:18
  • Сложно ... ладно, вроде понял отличие, благодарю. – MedvedevDev Aug 26 '17 at 23:20