JavaScript variables give names to values used by a program. Modern JavaScript uses const when a binding should not be reassigned and let when its value needs to change. var remains part of JavaScript and appears in older code, but its function-scoped behavior makes it less predictable for new code.
Basic declarations:
const siteName = "plus2net";
let visitors = 10;
visitors += 1;
console.log(siteName, visitors);
Variables are case-sensitive, must use valid identifiers, and have scope rules that determine where they can be accessed.
const course = "JavaScript";
let score = 75;
var legacyValue = "older style";
const and let are block-scoped. var is function-scoped (or global/module scoped depending on context) and can be redeclared in ways that often surprise beginners.
const. Change it to let only if you need to reassign that binding. Learn var so you can understand and maintain older JavaScript.total and Total are different identifiers._), or dollar sign ($).for and class cannot be used as variable names.const user2 = "Sam";
const _count = 5;
const $element = document.querySelector("#result");
// Invalid:
// const 2user = "Sam";
// const for = 5;
// const user-name = "Sam";
The original page stated that an ampersand (&) could be used in a variable name. That is incorrect for a normal JavaScript identifier, so this modernization corrects it.
Declaration creates the binding. Initialization supplies its first value. Assignment changes a value later.
let city; // declared, value is undefined
city = "Hyderabad"; // assignment
city = "Pune"; // reassignment
const country = "India"; // declaration + initialization
A const declaration must be initialized immediately and cannot later be reassigned.
JavaScript is dynamically typed. A variable declared with let can later reference a value of another type, although changing types without a good reason can make code harder to understand.
let value = 25;
console.log(typeof value); // number
value = "25";
console.log(typeof value); // string
See the dedicated typeof tutorial, parseInt(), and parseFloat().
A declared let variable without an initializer has the value undefined after its declaration is executed.
let result;
console.log(result); // undefined
console.log(typeof result); // "undefined"
Do not confuse this with accessing a let binding before its declaration; that is a temporal dead zone error, discussed below.
Scope controls where a binding can be accessed. Variables declared outside a function or block may belong to a wider scope. Function parameters and declarations inside a function are local to that function. let and const also respect block scope.
const greeting = "Hello";
function showGreeting() {
const name = "Asha";
console.log(greeting, name);
}
showGreeting();
// console.log(name); // ReferenceError
if (true) {
let blockValue = 10;
const message = "inside";
console.log(blockValue, message);
}
// console.log(blockValue); // ReferenceError
This modernizes the original page's local/global-variable lesson without losing the distinction it was teaching.
An inner scope can declare a variable with the same name as an outer scope. The inner declaration temporarily hides, or shadows, the outer one.
const message = "outside";
function showMessage() {
const message = "inside";
console.log(message);
}
showMessage(); // inside
console.log(message); // outside
Shadowing is valid but can become confusing when overused.
var declarations are hoisted and initialized with undefined. let and const bindings are also created for their scope before the declaration line, but they cannot be accessed until execution reaches the declaration. That inaccessible period is called the temporal dead zone.
console.log(oldValue); // undefined
var oldValue = 5;
// console.log(newValue); // ReferenceError
let newValue = 5;
Do not use hoisting as a coding technique. Declare variables close to where they are first needed.
const prevents reassignment of the binding; it does not freeze the object or array stored in it.
const student = { name: "Ravi" };
student.name = "Riya"; // allowed
const scores = [70, 80];
scores.push(90); // allowed
// student = {}; // TypeError: reassignment is not allowed
If immutability is required, that is a separate design decision; const alone does not recursively make an object immutable.
Array and object destructuring can declare several bindings from an existing value.
const user = { name: "Maya", age: 24 };
const { name, age } = user;
const colors = ["red", "green"];
const [firstColor, secondColor] = colors;
console.log(name, age, firstColor, secondColor);
In a classic browser script, some top-level var declarations become properties of window, while top-level let and const do not. Module code has its own module scope. Avoid relying on writable globals because they create name collisions and hidden dependencies.
var legacyGlobal = "visible on window in a classic script";
let modernGlobal = "not a window property";
console.log(window.legacyGlobal);
console.log(window.modernGlobal); // undefined
The original tutorial demonstrated reading a parent-window global through window.opener. That mechanism still exists in some same-origin situations, but modern security features such as noopener can deliberately remove the opener relationship. Do not design new applications around sharing writable globals between windows.
When two browsing contexts intentionally need to communicate, prefer explicit messaging such as window.postMessage() with strict origin checks. The older parent/child-window example is retained here as context rather than recommended architecture.
var without understanding that blocks do not scope it.const binding.const makes arrays or objects immutable.let or const binding before its declaration.Continue with typeof, functions and scope, JavaScript page structure, parseInt(), and parseFloat().
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.