В чем разница между var и let в Swift и JavaScript?

«В чем разница между var и let в Swift и JavaScript?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Swift и JavaScript эти ключевые слова имеют разную семантику, несмотря на одинаковое написание.

Swift

В Swift var и let определяют мутабельность (изменяемость) переменной.

let (константа) var (переменная)
Назначение Неизменяемая ссылка Изменяемая ссылка
Присваивание Только один раз при инициализации Можно многократно
Тип значений Может хранить mutable объекты Может хранить mutable объекты
Оптимизация Компилятор может оптимизировать Меньше оптимизаций

Пример в Swift:

// let - константа (нельзя изменить ссылку)
let constantArray = [1, 2, 3]
// constantArray = [4, 5, 6] // Ошибка: нельзя присвоить новое значение
constantArray.append(4) // OK: содержимое массива можно менять

// var - переменная (можно изменить ссылку)
var variableArray = [1, 2, 3]
variableArray = [4, 5, 6] // OK
variableArray.append(7) // OK

// let с value type
let constantInt = 10
// constantInt = 20 // Ошибка: value type полностью immutable

// Best practice: используйте let по умолчанию, var только когда нужно менять значение

JavaScript

В JavaScript var и let (а также const) определяют область видимости и поведение поднятия (hoisting).

var let const
Область видимости Function-scoped Block-scoped ({}) Block-scoped ({})
Поднятие (hoisting) Инициализируется как undefined Не инициализируется (TDZ) Не инициализируется (TDZ)
Переопределение Можно в той же области Нельзя в той же области Нельзя в той же области
Изменение значения Можно Можно Нельзя (для примитивов)

Пример в JavaScript:

// var - function-scoped
function varExample() {
    if (true) {
        var x = 10;
    }
    console.log(x); // 10 (видна вне блока if)
}

// let - block-scoped
function letExample() {
    if (true) {
        let y = 20;
        console.log(y); // 20
    }
    // console.log(y); // ReferenceError: y is not defined
}

// Temporal Dead Zone (TDZ) для let/const
console.log(a); // undefined (var поднята)
var a = 1;

// console.log(b); // ReferenceError (let в TDZ)
let b = 2;

// const для констант
const PI = 3.14159;
// PI = 3.14; // TypeError: Assignment to constant variable

const obj = { name: "John" };
obj.name = "Jane"; // OK: можно менять свойства объекта
// obj = { name: "Bob" }; // TypeError: нельзя переприсвоить ссылку

Сравнительная таблица

Язык Ключевое слово Основное назначение Область видимости Мутабельность
Swift let Константа (immutable reference) Любая Зависит от типа данных
Swift var Переменная (mutable reference) Любая Зависит от типа данных
JavaScript var Переменная (устаревшее) Function-scoped Можно изменять
JavaScript let Переменная (современное) Block-scoped Можно изменять
JavaScript const Константа (современное) Block-scoped Нельзя переприсвоить

Рекомендации:

  • Swift: Используйте let по умолчанию, var только когда значение должно меняться.
  • JavaScript: Используйте const по умолчанию, let когда значение меняется, избегайте var в новом коде.