Когда мы изучаем язык программирования, появляются несколько основных понятий, таких как объявление переменных, и они настолько просты, что мы можем начать их использовать без каких-либо знаний об их функционировании.
Я знаю о чем вы подумали: «Зачем вы тратите время на то, чтобы написать нам об этом?»
Потому что я думаю, что стоит потратить несколько минут, чтобы глубже понять эти элементы, каково их значение и как мы должны их использовать. Это поможет вам избежать некоторых распространенных ошибок и написать код лучше.
В этой статье мы сосредоточимся на том, как хранить данные в JavaScript.
Var
«Давным-давно в далекой галактике…» единственным вариантом определения переменных в JavaScript было использование ключевого слова var, и этого было достаточно для управления данными в коде. Но с введением стандарта ES6 некоторые странности и недостатки старого JS стали довольно очевидными:
1. Область действия: ключевое слово var позволяет определять переменные только в глобальной и локальной области (либо в области функции). Неважно, сколько у вас вложенных блоков кода, есть только эти две возможности.
2. Константы: если вы хотите определить что-то, что не будет изменяться во время выполнения кода, вы можете положиться только на здравый смысл разработчиков. Мы можем использовать некоторые полезные соглашения, чтобы разъяснить смысл (например, прописные буквы), но нет ничего, что могло бы гарантировать, что значение не изменится.
3. Переопределение переменных: вы можете повторять объявление одной и той же переменной, столько раз, сколько хотите (в одной и той же области видимости), и это немного сбивает с толку, если вы хотите сохранить переменные уникальными.
Определения
Прежде чем начать с технических вещей, давайте введем некоторые общие определения:
Переменная — это «контейнер», в котором хранятся многократно использованные данные (очень тривиально).
Идентификаторы — это имена переменных (тоже очень тривиально).
Блок — это фрагмент кода, разделенный парой фигурных скобок (ccskrf), например: if, for, function, и. т. д.
Область действия, определяет видимость переменных внутри кода. Если у вас есть какие-либо сомнения, спросите себя: «Где в коде видна моя переменная?»
ПРИМЕЧАНИЕ. Пожалуйста, не путайте область действия с контекстом выполнения, который является разными.
** Контекст (или контекст выполнения) ** — это среда, в которой выполняется код JavaScript. Для простоты можно сказать, что контекст — это объект, которому принадлежит код, а this — это ключевое слово, которое является ссылкой на него. Поэтому спросите себя: «На какой объект ссылается this?»
Теперь предположим, что наш разработчик очень увлечен Star Wars (это хорошо), но с подозрением относится к новым стандартам, таким как ES6 (что плохо), хотя существует он уже некоторое время. Поэтому он предпочитает писать свой код в старом стиле ES5, и это будет выглядеть так:
console.log("I am a %s", jedi);
var jedi = "Ani";
// выведите переменную jedi перед ее определением
// => Я undefined
function useTheForce(comeToTheDarkSide) {
var jedi = "Obi-Wan Kenobi";
var jedi = "Anakin Skywalker";
if (comeToTheDarkSide) {
var jedi = "Darth Vader";
console.log("I am %s", jedi);
// => I am Darth Vader
}
console.log("I am %s", jedi);
// Я Darth Vader
}
useTheForce(true);
console.log("I am %s", jedi);
// =>Я Ani
Как вы видите, есть три блока кода (включая и глобальный), но только две области видимости. Это из-за того, что код в скобках if не создает область видимости. Консоль выдаст «Я Дарт Вейдер» два раза, а затем «Я Ани» в глобальном масштабе.
Также обратите внимание, что одна и та же переменная объявляется два раза подряд внутри функции, а затем еще раз в выражении if. Это означает, что мы имеем объявление одной и той же переменной в одной и той же области видимости три раза, из-за чего выдается исключение.
Последним, но не менее важным является вывод первого log: мы выведем значение нашей переменной перед ее определением. Это совершенно законно с var и называется «Поднятием (hoisting)».
«Подъем» предполагает, что объявленные переменные и функции физически перемещаются в начало вашего кода. Технически происходит объявления переменных и функций, которые помещаются в память на этапе компиляции, но остаются в коде именно там, где вы их написали. Основная важность подъема состоит в том, что он позволяет вам использовать функции перед тем, как объявлять их в своем коде.
Об этом вы можете почитать здесь.
В нашем примере объявление переменной «jedi» помещается в память и инициализируется значением по умолчанию (undefined).
Let
На данный момент наш разработчик понимает, что ES6 не так уж и плох, и он решает дать let шанс:
console.log("I am a %s", jedi);
let jedi = "Ani";
// выведем переменную jedi перед ее определением
// => Uncaught ReferenceError: Невозможно получить доступ к "jedi" до инициализации
function useTheForce(comeToTheDarkSide) {
let jedi = "Obi-Wan Kenobi";
let jedi = "Anakin Skywalker";
// => Uncaught SyntaxError: Идентификатор 'джедай' уже объявлен
if (comeToTheDarkSide) {
var jedi = "Darth Vader";
console.log("I am %s", jedi);
// => Я Darth Vader
}
console.log("I am %s", jedi);
// Я Anakim Skywalker
}
useTheForce(true);
console.log("I am %s", jedi);
// => Я Ani
Но вскоре он понимает, что он не может просто поменять ключевое слово var на let, для этого нужно сделать некоторые исправления:
«Подъем» не работает таким же образом: переменная переводится в состояние с именем Temporal Dead Zone * * и не инициализируется до тех пор, пока определение не будет оценено. В нашем примере выдает ошибку: reference error.
переназначение запрещено, определение переменной в области видимости должно быть уникальным. При попытке выдается ошибка: SyntaxError.
Оператор if является допустимой областью действия блока, поэтому объявление «jedi» внутри него является уникальным.
Теперь код должен стать таким:
let jedi = "Ani";
console.log("I am a %s", jedi);
// print jedi variable before defining it
// => Я Ani (пред его определение) : 0
function useTheForce(comeToTheDarkSide) {
let jedi = "Obi-Wan Kenobi";
let jedi = "Anakin Skywalker";
if (comeToTheDarkSide) {
var jedi = "Darth Vader";
console.log("I am %s", jedi);
// => Я Darth Vader
}
console.log("I am %s", jedi);
// Я Anakim Skywalker
}
useTheForce(true);
console.log("I am %s", jedi);
Const
Теперь, когда вы знаете все о let, будет легко представить вас const. По сути, мы можем сказать, что const похоже на let, но вы не можете переназначить другое значение. Вам также необходимо знать, что присвоение разрешено только во время объявления const.
function useTheForce(comeToTheDarkSide) {
const jedi = "Yoda";
if (true) {
jedi = "Darth Yoda";
console.log("I am %s", jedi);
// => TypeError: Assignement to constant variable.
}
}
useTheForce(true);
Предположим, что в нашем примере «jedi» является константой со значением «Yoda», если мы попытаемся изменить значение внутри оператора if, это выдаст нам ошибку TypeError, и это понятно, потому что Yoda никогда не присоединится к темной стороне.
Заключение
Когда в языках невозможно выразить концепцию словами, вводится новый концепт, чтобы заполнить пробел. Это правильно для английского языка (ссылка.), итальянского, эсперанто, эвокезе (я полагаю) и т. д. Это еще более верно для языков программирования, таких как JavaScript.
Теперь вы знаете, что вы можете:
- Объявлять переменные в области видимости блока и выделять для них память только при оценке блока
- Сохранять объявления переменных уникальными внутри области видимости, избегая того, чтобы разработчик по ошибке мог переопределить переменную, используемую в другой части кода (с другим значением)
- Можем убедиться, что переменная, сохраненная в const, не изменится в любое время.
Мое последний совет — это использовать const в качестве выбора по умолчанию. Когда вам нужно переназначить переменную, используйте ** let ** (как в циклах). И используйте var, когда… нет, вам больше не нужен var, правда
Спасибо за внимание.
Быстрые ответы на вопросы по JavaScript
Автор: Rapprogtrain