var, let, and const are the three ways to declare variables in JavaScript. They differ in scope (function vs block), reassignment rules, and hoisting behavior.
var is function-scoped and can be redeclared and reassigned; it is hoisted and initialized as undefined. let is block-scoped ({}), can be reassigned but not redeclared in the same scope, and lives in a Temporal Dead Zone until its declaration line. const is also block-scoped but must be initialized at declaration and cannot be reassigned — though for objects and arrays the contents can still be mutated (only the binding is constant). Modern JavaScript favors const by default, let when reassignment is needed, and avoids var.
In a Playwright/Selenium test you use const for locators that never change (const loginBtn = page.locator('#login')) and let for a counter you increment in a loop. Using var inside a for-loop with async callbacks is a classic bug source because the single function-scoped var is shared across all iterations.
A candidate writes: for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); }. It prints 3, 3, 3 instead of 0, 1, 2. Explain why and fix it.