Це питання задають не часто, але воно все ще актуальне тому варто розуміти основні відмінності:
Область видимості
var має функціональну область видимості (function scope) тому якщо ми оголошуємо змінну var в блоці {}, вона все одно буде глобальна в рамках функції де була оголошена або в рамках глобального обʼєкту.
Hoisting
В цілому, як var так і let піднімаються на початок області видимості, але є суттєва різниця при спробі доступу до них.
var піднімається і присвоюється значення undefined, яке ми отримуємо при доступі let піднімається, але при спробі доступу, отримаємо помилку.
Повторне оголошення
var можна оголосити повторно в межах однієї області.
let не можна повторно оголосити в межах одного блоку, бо отримаємо помилку.