В чём разница между var, let и const в javascript

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

Область видимости определяет, где в коде программы будут доступны переменные и функции. В JavaScript есть два типа области видимости — глобальная и локальная (global scope и function scope). Согласно официальной спецификации:


То есть, если вы создаёте переменную внутри функции с оператором , то она будет доступна только внутри этой функции и вложенных в неё функциях.

function getDate () {  var date = new Date()return date}getDate()console.log(date) //  Reference Error

В коде выше, мы пытаемся получить доступ к переменной вне функции, в которой она была объявлена. Так как переменная ограничена областью видимости функции , она доступна только внутри или для любой вложенной в неё функции (как в примере ниже).

function getDate () {  var date = new Date()function formatDate () {    return date.toDateString().slice(4) //    }return formatDate()}getDate()console.log(date) //  Reference Error

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

discountPrices(, .5)

Реализация:

function discountPrices (prices, discount) {  var discounted = []for (var i = 0; i < prices.length; i++) {    var discountedPrice = prices * (1 - discount)    var finalPrice = Math.round(discountedPrice * 100) / 100    discounted.push(finalPrice)  }return discounted}

Выглядит довольно просто, но что происходит в области видимости блока? Обратите внимание на цикл. Доступны ли переменные, которые объявлены внутри цикла, вне его? Оказывается, что да

function discountPrices (prices, discount) {  var discounted = []for (var i = 0; i < prices.length; i++) {    var discountedPrice = prices * (1 - discount)    var finalPrice = Math.round(discountedPrice * 100) / 100    discounted.push(finalPrice)  }console.log(i) // 3  console.log(discountedPrice) // 150  console.log(finalPrice) // 150return discounted}

Если JavaScript это единственный язык программирования, которым вы владеете, то вы не заметите ничего странного. Но если вы перешли с другого языка, вы, вероятно, немного запутались в том, что здесь происходит.

Здесь нет ошибки, это просто немного необычно. К тому же, у нас нет необходимости иметь доступ к , , и вне цикла . Для нас в этом нет никакой пользы, более того, в некоторых случаях это может мешать. Тем не менее, поскольку переменные, объявлены оператором , они относятся к функции и доступны вне цикла.

Теперь вы знаете, что такое область видимости, инициализация и объявление переменных; нам осталось разобраться с понятием «поднятие переменной» (hoisting), прежде чем перейти к и .

Переменная

Переменная – это «именованное хранилище» для данных. Мы можем использовать переменные для хранения товаров, посетителей и других данных.

Для создания переменной в JavaScript используйте ключевое слово .

Приведённая ниже инструкция создаёт (другими словами: объявляет или определяет) переменную с именем «message»:

Теперь можно поместить в неё данные, используя оператор присваивания :

Строка сохраняется в области памяти, связанной с переменной. Мы можем получить к ней доступ, используя имя переменной:

Для краткости можно совместить объявление переменной и запись данных в одну строку:

Мы также можем объявить несколько переменных в одной строке:

Такой способ может показаться короче, но мы не рекомендуем его. Для лучшей читаемости объявляйте каждую переменную на новой строке.

Многострочный вариант немного длиннее, но легче для чтения:

Некоторые люди также определяют несколько переменных в таком вот многострочном стиле:

…Или даже с запятой в начале строки:

В принципе, все эти варианты работают одинаково. Так что это вопрос личного вкуса и эстетики.

вместо

В старых скриптах вы также можете найти другое ключевое слово: вместо :

Ключевое слово – почти то же самое, что и . Оно объявляет переменную, но немного по-другому, «устаревшим» способом.

Есть тонкие различия между и , но они пока не имеют для нас значения. Мы подробно рассмотрим их в главе Устаревшее ключевое слово «var».

Redeclaring

Redeclaring a JavaScript variable is allowed anywhere in a program:

var x = 2;    //  Allowedvar x = 3;    //  Allowed x = 4;        //  Allowed

Redeclaring or reassigning an existing or variable to , in the same scope, or in the same block, is not allowed:

var x = 2;         // Allowed const x = 2;       // Not allowed{  let x = 2;     // Allowed   const x = 2;   // Not allowed}

Redeclaring or reassigning an existing variable, in the same scope, or in the same block, is not allowed:

const x = 2;       // Allowed const x = 3;       // Not allowedx = 3;             // Not allowed var x = 3;         // Not allowed let x = 3;         // Not allowed{  const x = 2;   // Allowed   const x = 3;   // Not allowed  x = 3;         // Not allowed  var x = 3;     // Not allowed  let x = 3;     // Not allowed}

Redeclaring a variable with , in another scope, or in another block, is allowed:

JS Tutorial

JS HOMEJS IntroductionJS Where ToJS OutputJS StatementsJS SyntaxJS CommentsJS VariablesJS OperatorsJS ArithmeticJS AssignmentJS Data TypesJS FunctionsJS ObjectsJS EventsJS StringsJS String MethodsJS NumbersJS Number MethodsJS ArraysJS Array MethodsJS Array SortJS Array IterationJS DatesJS Date FormatsJS Date Get MethodsJS Date Set MethodsJS MathJS RandomJS BooleansJS ComparisonsJS ConditionsJS SwitchJS Loop ForJS Loop WhileJS BreakJS Type ConversionJS BitwiseJS RegExpJS ErrorsJS ScopeJS HoistingJS Strict ModeJS this KeywordJS LetJS ConstJS Arrow FunctionJS DebuggingJS Style GuideJS Best PracticesJS MistakesJS PerformanceJS Reserved WordsJS VersionsJS Version ES5JS Version ES6JS JSON

Аналогия из жизни

Мы легко поймём концепцию «переменной», если представим её в виде «коробки» для данных с уникальным названием на ней.

Например, переменную можно представить как коробку с названием и значением внутри:

Мы можем положить любое значение в коробку.

Мы также можем изменить его столько раз, сколько захотим:

При изменении значения старые данные удаляются из переменной:

Мы также можем объявить две переменные и скопировать данные из одной в другую.

Функциональные языки программирования

Примечательно, что существуют функциональные языки программирования, такие как Scala или Erlang, которые запрещают изменять значение переменной.

В таких языках однажды сохранённое «в коробку» значение остаётся там навсегда. Если нам нужно сохранить что-то другое, язык заставляет нас создать новую коробку (объявить новую переменную). Мы не можем использовать старую переменную.

Хотя на первый взгляд это может показаться немного странным, эти языки вполне подходят для серьёзной разработки. Более того, есть такая область, как параллельные вычисления, где это ограничение даёт определённые преимущества. Изучение такого языка (даже если вы не планируете использовать его в ближайшее время) рекомендуется для расширения кругозора.

Redeclaring

Redeclaring a JavaScript variable with is allowed anywhere in a program:


var x = 2; // Now x is 2   var x = 3;// Now x is 3

Redeclaring a variable with , in the same scope, or in the same block, is not allowed:

var x = 2;       // Allowed let x = 3;       // Not allowed{  var x = 4;   // Allowed   let x = 5   // Not allowed}

Redeclaring a variable with , in the same scope, or in the same block, is not allowed:

let x = 2;       // Allowed let x = 3;       // Not allowed{  let x = 4;   // Allowed   let x = 5;   // Not allowed}

Redeclaring a variable with , in the same scope, or in the same block, is not allowed:

let x = 2;       // Allowed var x = 3;       // Not allowed{  let x = 4;   // Allowed   var x = 5;   // Not allowed}

Redeclaring a variable with , in another scope, or in another block, is allowed:

const

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

Следовательно, const должен быть всегда инициализирован при объявлении, иначе возникает ошибка.

const foo = “something”;foo = “other thing”; // Uncaught TypeError: Assignment to constant variable. const bar; //Uncaught SyntaxError: Missing initializer in const declaration

Стоит отметить, что когда const связан с объектом, сам объект нельзя изменить, и const будет указывать на тот же самый объект. Однако изменения внутри объекта допустимы.

const score = {visitors: 0, home: 0};score.visitors = 1; // Можноscore = {visitors: 1, home: 1}; // Uncaught TypeError: Assignment to constant variable.// Нельзя

Один последний факт:

Переменные, объявленные внутри функции без ключевого слова, станут глобальными переменными. Взглянем на это в следующем примере:

function funFact() { isGloballyAvailable = true;}funFact();console.log(isGloballyAvailable); // записывает true

Чтобы понять что происходит, нам нужно вернуться назад к понятию поднятия. Обычно при инициализации переменной в нашем коде интерпретатор ищет «поднятые переменные» и затем присваивает или переназначает значение переменной. Однако, когда интерпретатор не может найти переменную внутри функции, он ищет ее среди переменных родительской функции, пока не дойдет до глобальной области видимости.

В нашем случае интерпретатор не найдет ‘isGloballyAvailable’ даже в глобальной области видимости, поэтому он автоматически туда ее добавит.

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

Так, когда использовать var, let или const?

ES2015(ES6) представил let и const. Зачем JavaScript разработчикам их вводить? Может, чтобы исправить проблемы, возникающие с var, или для улучшения читабельность кода?

Одна главная проблема с var связана с тем, что он позволяет переназначать переменные в коде, из-за чего не выбрасываются ошибки. Это приводит к различным побочным эффектам в коде. 

Распространенное мнение, которое сходится с моим:

Всегда отдавайте предпочтение const, если значение, присвоенное переменной, не изменится. Это подскажет будущим разработчикам, что у переменной неизменное значение.

А let используйте, если значение в будущем изменится. 

Где бы был полезен var, я не представляю. 

  • Новые API интернационализации в JavaScript
  • 7 FrontEnd трендов и инструментов для JavaScript на 2020
  • Рекомендации по изучению JavaScript

Читайте нас в телеграмме и vk

Перевод статьиGemhar Rafi — var, let and const in JavaScript Decoded…

var VS let VS const

Сперва сравним var и let. Главное отличие let в том, что область видимости переменной ограничивается блоком, а не функцией. Другими словами, переменная, созданная с помощью оператора let, доступна внутри блока, в котором она была создана и в любом вложенном блоке. Говоря «блок», я имею ввиду всё что вложено между фигурными скобками {}, как например в цикле for или условии if.

Давайте в последний раз вернёмся к нашей функции discountPrices.

Помните, что мы можем логировать i, discountedPrice, и finalPrice вне цикла for, так как они созданы с помощью var, а значит видны в пределах функции. Но, что, если мы заменим оператор var на let и попробуем выполнить код.

Вот что мы получим: ReferenceError: i is not defined. Это подтверждает, что let переменные ограничены блоком, а не функцией. Поэтому попытка получить к ним доступ приводит к ошибке.

var VS letvar: function scopedlet: block scoped

Следующее отличие связано с поднятием переменной. Ранее мы определили, что интерпретатор в JavaScript присваивает переменным значение undefined по умолчанию во время фазы «Создания». Вы даже видели это в действии, логируя переменную до её объявления (и получили undefined).

Я даже не могу придумать причину, по которой стоит запрашивать переменную до её объявления. Мне кажется, что получать по умолчанию ReferenceError лучше, чем возврат undefined.

Кстати, именно это и делает let, т.е. вы получите ошибку ReferenceError вместо значения undefined, если запросите переменную, созданную оператором let, до её объявления.


let VS const

Различия между var и let мы выяснили, а что насчёт const? Получается, что const и let почти одно и тоже. И всё же есть одно отличие: значение переменной, объявленной с помощью const, нельзя переназначить. Это можно увидеть в примере ниже:

Итак, если вы хотите, чтобы переменная была неизменной, используйте const. Ну, почти. На самом деле оператор const не делает переменную неизменной, а только не даёт переназначать её значение. Вот хороший пример:

Обратите внимание, что изменение свойства объекта не является его переназначением, поэтому, даже если объект объявлен с помощью const, это не означает, что вы не можете изменить ни одно из его свойств. Это только означает, что вы не можете переназначить его на новое значение

Теперь главный вопрос: что следует использовать var, let, или const? Наиболее популярное мнение, под которым подписываюсь и я, — всегда использовать const, кроме тех случаев, когда вы знаете, что переменная будет изменятся. Используя const, вы как бы говорите себе будущему и другим разработчикам, которые будут читать ваш код, что эту переменную изменять не следует. Если вам нужна изменяемая переменная (например, в цикле for), то используйте let.

Таким образом, между изменяемыми и неизменяемыми переменными осталось не так много различий. Это означает, что вам больше не придётся использовать var.

Теперь «непопулярное» мнение, хотя оно и обоснованно (пока): вы никогда не должны использовать const, потому что, хотя вы пытаетесь показать, что переменная неизменна, это не совсем правда (мы видели это на примере выше). Разработчики, которые разделяют это мнение, всегда используют let, за исключением случаев когда переменная действительно является константой, например _LOCATION_ = ….

Повторим для закрепления. Область видимости var переменных ограничена функцией, если вы обратитесь к переменной до её объявления, то получите undefined. const и let ограничены блоком, а попытка обратится к переменной до её объявления, вернётся ошибкой ReferenceError. И наконец, разница между let и const в том, что в первом случае вы можете изменить значение переменной, а во втором нет.

Читайте нас в телеграмме и vk

Перевод статьи Tyler McGinnisWhen to use var vs let vs const in JavaScript

JavaScript Identifiers

All JavaScript variables must be identified with unique names.

These unique names are called identifiers.

Identifiers can be short names (like x and y) or more descriptive names (age, sum, totalVolume).

The general rules for constructing names for variables (unique identifiers) are:

  • Names can contain letters, digits, underscores, and dollar signs.
  • Names must begin with a letter
  • Names can also begin with $ and _ (but we will not use it in this tutorial)
  • Names are case sensitive (y and Y are different variables)
  • Reserved words (like JavaScript keywords) cannot be used as names

JavaScript identifiers are case-sensitive.

Правила именования

  • Правило 1.

    Никакого транслита. Только английский.

    Неприемлемы:

    Подойдут:

    Чем плох транслит?

    Во-первых, среди разработчиков всего мира принято использовать английский язык для имён переменных. И если ваш код потом попадёт к кому-то другому, например вы будете в команде больше чем из одного человека, то велик шанс, что транслит ему не понравится.

    Во-вторых, русский транслит хуже читается и длиннее, чем названия на английском.

    В-третьих, в проектах вы наверняка будете применять библиотеки, написанные другими людьми. Многое уже готово, в распоряжении современного разработчика есть масса инструментов, все они используют названия переменных и функций на английском языке, и вы, конечно, будете их использовать. А от кода, где транслит перемешан с английским – волосы могут встать дыбом, и не только на голове.

    Если вы, вдруг, не знаете английский – самое время выучить.

  • Правило 2.

    Использовать короткие имена только для переменных «местного значения».

    Называть переменные именами, не несущими смысловой нагрузки, например , , , – можно только в том случае, если они используются в небольшом фрагменте кода и их применение очевидно.

    Вообще же, название переменной должно быть понятным. Иногда для этого нужно использовать несколько слов.

  • Правило 3.


    Переменные из нескольких слов пишутся .

    Например:

    Этот способ записи называется «верблюжьей нотацией» или, по-английски, «camelCase».

    Существует альтернативный стандарт, когда несколько слов пишутся через знак подчёркивания :

    Преимущественно в JavaScript используется вариант , в частности во встроенных языковых и браузерных функциях. Поэтому целесообразно остановиться на нём.

    Ещё одна причина выбрать «верблюжью нотацию» – запись в ней немного короче, чем с подчёркиванием, т.к. не нужно вставлять .

  • Правило последнее, главное.

    Имя переменной должно максимально чётко соответствовать хранимым в ней данным.

    Придумывание таких имён – одновременно коротких и точных, при которых всегда понятно, что где лежит, приходит с опытом, но только если сознательно стремиться к этому.

Позвольте поделиться одним небольшим секретом, который очень прост, но позволит улучшить названия переменных и сэкономит время.

Бывает так, что, написав код, мы через некоторое время к нему возвращаемся, надо что-то поправить. И мы примерно помним, что переменная, в которой хранится нужное вам значение, называется… Ну, скажем, . Мы ищем её в коде, не находим, но, разобравшись, обнаруживаем, что на самом деле переменная называлась вот так: .

Если мы ищем переменную с одним именем, а находим – с другим, то зачастую самый лучший ход – это переименовать переменную, чтобы имя было тем, которое вы искали.

То есть, в коде , а мы её переименуем на ту, которую искали: .

Зачем? Дело в том, что в следующий раз, когда вы захотите что-то поправить, то вы будете искать по тому же самому имени. Соответственно, это сэкономит вам время.

Есть причина и поважнее. Поскольку именно это имя переменной пришло в голову – скорее всего, оно больше соответствует хранимым там данным, чем то, которое мы придумали изначально. Исключения бывают, но в любом случае – такое несовпадение – это повод задуматься.

Чтобы удобно переименовывать переменную, нужно использовать хороший редактор JavaScript, тогда этот процесс будет очень простым и быстрым.

Если коротко…

Смысл имени переменной – это «имя на коробке», по которому мы сможем максимально быстро находить нужные нам данные.

Не нужно бояться переименовывать переменные, если вы придумали имя получше.

Современные редакторы позволяют делать это очень удобно и быстро. Это в конечном счёте сэкономит вам время.

Храните в переменной то, что следует

Бывают ленивые программисты, которые, вместо того чтобы объявить новую переменную, используют существующую.

В результате получается, что такая переменная – как коробка, в которую кидают то одно, то другое, то третье, при этом не меняя название. Что в ней лежит сейчас? А кто его знает… Нужно подойти, проверить.

Сэкономит такой программист время на объявлении переменной – потеряет в два раза больше на отладке кода.

«Лишняя» переменная – добро, а не зло.

Declaring (Creating) JavaScript Variables

Creating a variable in JavaScript is called «declaring» a variable.

You declare a JavaScript variable with the keyword:

var carName;

After the declaration, the variable has no value (technically it has the value of ).

To assign a value to the variable, use the equal sign:

carName = «Volvo»;

You can also assign a value to the variable when you declare it:

var carName = «Volvo»;

In the example below, we create a variable called and assign the value «Volvo» to it.

Then we «output» the value inside an HTML paragraph with id=»demo»:

Example

<p id=»demo»></p><script> var carName = «Volvo»; document.getElementById(«demo»).innerHTML = carName; </script>

It’s a good programming practice to declare all variables at the beginning of a script.


С этим читают