Недавно джавист спросил меня: "А в чём вообще проблема использования
var в JavaScript?". Я на автомате ответила что-то про замыкания, но потом поняла, что конкретику-то уже подзабыла. А значит, как я люблю, самое время покопаться и вспомнить, что же с ним не так.
Почему var считается устаревшим?Когда в ES6 в 2015 году появились
let и
const, почти весь мир фронтенда перешёл на них. Но
var никуда не делся и до сих пор встречается в старом коде. Почему же все от него отказались?
1. var живёт в рамках функции, а не блокаЕсли объявить
var внутри
if,
for или `{}`-блока, он доступен во всей функции, а если функция не задана – в глобальной области видимости.
function example() {
if (true) {
var message = "Hello";
}
console.log(message); // "Hello"
}
example();
2. var поднимается (hoisting), но остаётся undefinedПеременные, объявленные через
var, поднимаются в начало функции и принимают значение
undefined, если к ним обратиться до объявления.
console.log(user); // undefined
var user = "Cat";
Такое поведение, что в первом, что во втором случае, очень нетипично для большинства языков программирования и в частности поэтому может запутать.
Почему работу с var не исправили сразу, как заметили проблемы?Когда JavaScript создавался в 1995 году, он задумывался как язык для небольших скриптов, которые просто добавляли интерактивность на веб-страницы. Никто не думал, что на нем будут писать сложные приложения с десятками тысяч строк кода. Поэтому такие вещи, как
var с функциональной областью видимости, не казались проблемой – ведь весь скрипт обычно находился в одном файле и выполнялся сверху вниз. Но затем веб-разработка начала усложняться. JS стал полноценным языком для больших приложений, а старые решения начали тянуть за собой ошибки.
В ES6 наконец-то добавили
let и
const, чтобы исправить проблемы
var, но полностью убрать или изменить принцип его работы было невозможно. JavaScript выполняется на машинах пользователей, а браузеры у всех разные – кто-то сидит на новой версии Chrome, а кто-то на старом IE. В отличие от компилируемых языков, где ты контролируешь, какая версия используется, в вебе это сделать невозможно. Поэтому
var остался в языке таким, какой он есть, ради обратной совместимости.
К слову, может показаться, что особенности
var – это только источник багов, но в некоторых случаях это удобно. Например,
hoisting позволяет вызывать функции до их объявления.
В общем-то, JS менялся и продолжает меняться под давлением времени, и отказ от
var – одна из тех вещей, которые сделали разработку на этом языке чуть предсказуемее.