When AI generates JavaScript, every variable uses one of three keywords: const, let, or var. Understanding the difference is how you spot stale patterns in AI output, catch reassignment bugs, and know when the generated code is using the right declaration for the job.
Not all variable declarations are equal. Some should never change (a configuration value), while others need to be updated (a counter in a loop). JavaScript gives you three ways to declare variables, and AI doesn't always pick the right one.
const: When you want a guarantee
const is your default choice. It creates a variable that cannot be reassigned once initialized. Think of it like writing with a permanent marker, once it's set, it's set.
const API_URL = "https://api.example.com";
const MAX_RETRIES = 3;
const userName = "Alice";
// This will throw an error:
// userName = "Bob"; // TypeError: Assignment to constant variableBut wait, const doesn't make values immutable, just the binding. If you store an object or array, you can still modify what's inside:
const user = { name: "Alice", age: 25 };
user.age = 26; // This works fine!
user.name = "Bob"; // This too!
// But this won't work:
// user = { name: "Charlie" }; // TypeError!const, JavaScript creates a binding in memory that points to a value. The binding itself is locked, you can't make it point somewhere else. But if that value is an object, the object itself can still be modified. We'll explore immutability patterns later when we dive deeper into objects.let: For things that change
Sometimes you genuinely need a variable that changes. Counters, accumulators, loop indices, these are perfect for let:
let score = 0;
score = 10;
score += 5;
let currentUser = null;
currentUser = fetchUser(); // Assigned laterThe temporal dead zoneWhat is temporal dead zone?The period between entering a scope and the let/const declaration being reached, during which accessing the variable throws a ReferenceError.
Here's something that trips up AI tools: they sometimes reference a let variable before it's declared, even though the declaration gets "hoisted" (moved to the top of the scopeWhat is scope?The area of your code where a variable is accessible; variables declared inside a function or block are invisible outside it.):
console.log(name); // ReferenceError!
let name = "Alice";This is actually a feature, not a bug. It prevents you from accidentally using undefined variables.
var: Just don't
var was JavaScript's original variable declaration, introduced in 1995. It has two major problems that have caused countless bugs over the decades.
var in their output, especially when trained on older tutorials and Stack Overflow answers. They also redeclare variables with var inside the same scope without warning, something that silently succeeds with var but throws an error with let (which is the behavior you want). Always replace var with const or let in AI-generated code.Problem 1: Function scopeWhat is scope?The area of your code where a variable is accessible; variables declared inside a function or block are invisible outside it., not block scope
function example() {
if (true) {
var secret = "I'm inside the if block";
}
console.log(secret); // Works! (But shouldn't)
}With var, the variable exists throughout the entire function, not just the block where it was declared. This violates the principle of least privilege, variables should only be accessible where they're needed.
Problem 2: Variable hoistingWhat is hoisting?JavaScript's behavior of moving function and variable declarations to the top of their scope during compilation, so they can be referenced before they appear in the code. quirks
console.log(mystery); // undefined (not an error!)
var mystery = "What am I?";var declarations are hoisted to the top of their scope and initialized with undefined. This silently fails instead of throwing an error, making bugs harder to find.
Naming conventions in AI output
AI-generated code usually follows naming conventions, but not always consistently. Here's what to expect and what to enforce:
| Bad | Good | Why |
|---|---|---|
x | userCount | What does x represent? |
n | numberOfItems | Be descriptive |
data | userProfile | What kind of data? |
tmp | tempFilePath | Even temporaries need context |
isValid | isEmailValid | Valid what? |
Naming rules
- Must start with a letter, underscore, or dollar sign:
name,_private,$element - Can contain letters, numbers, underscores, dollar signs:
userName2,_tempValue - Cannot use reserved words:
const,function,class, etc. - Case-sensitive:
Nameandnameare different variables
Style conventions you'll see in AI output
JavaScript uses camelCase for regular variables. AI usually gets this right, but watch for inconsistencies when it mixes conventions across generated files:
const userName = "Alice"; // camelCase ✓
const user_name = "Alice"; // snake_case (Python style)
const UserName = "Alice"; // PascalCase (usually for classes)
const USERNAME = "Alice"; // SCREAMING_SNAKE_CASE (usually for constants)Quick reference
| Keyword | Scope | Hoisted? | Reassignable? | When to use |
|---|---|---|---|---|
const | Block | Yes (TDZ) | No | Default choice, use everywhere unless reassignment is needed |
let | Block | Yes (TDZ) | Yes | Counters, accumulators, values that change |
var | Function | Yes (as undefined) | Yes | Never, legacy code only |
// const for things that don't change
const PI = 3.14159;
const API_URL = "https://api.example.com/v1";
const greeting = "Hello World";
// let for things that do change
let count = 0;
count += 1;
let currentUser = null;
currentUser = { name: "Alice", id: 123 };
// Template literals use backticks
const message = `Welcome, ${currentUser.name}! You are visitor #${count}`;
console.log(message);
// const with objects, the binding is constant, not the object
const config = { theme: "dark", fontSize: 16 };
config.theme = "light"; // This works fine
console.log(config.theme); // "light"