JavaScript variables are essential for storing and manipulating data in your code. Here's a comprehensive guide to understanding them:
Declaring Variables
You can declare variables using var
, let
, or const
:
-
var
: Function-scoped, can be re-declared and updated.
var name = "John";
name = "Doe";
-
let
: Block-scoped, can be updated but not re-declared within the same scope.
let age = 25;
age = 26;
-
const
: Block-scoped, cannot be updated or re-declared, and must be initialized at the time of declaration.
const birthYear = 1995;
Variable Scope
- Global Scope: Variables declared outside any function have global scope.
-
Function Scope: Variables declared with
var
inside a function are function-scoped. -
Block Scope: Variables declared with
let
orconst
inside a block (e.g.,{}
) are block-scoped.
Hoisting
JavaScript hoists var
declarations to the top of their scope, but not their initializations. let
and const
are also hoisted but are not initialized.
Example
console.log(x); // undefined
var x = 5;
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
let
The let
keyword in JavaScript is used to declare variables that are block-scoped, meaning they are only accessible within the block they are defined in (e.g., within {}
braces). Here are some key points about let
:
Characteristics of let
-
Block Scope: Variables declared with
let
are confined to the block in which they are declared.
if (true) {
let message = "Hello!";
console.log(message); // "Hello!"
}
console.log(message); // ReferenceError: message is not defined
- No Hoisting: Declarations are hoisted but not initialized, leading to a "temporal dead zone" until the declaration is encountered.
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 10;
-
Reassignment Allowed: You can reassign a
let
variable, but you cannot redeclare it within the same scope.
let count = 1;
count = 2; // Allowed
let count = 3; // SyntaxError: Identifier 'count' has already been declared
Example Usage
let name = "Alice";
name = "Bob"; // This is fine
if (true) {
let age = 30;
console.log(age); // 30
}
// console.log(age); // ReferenceError: age is not defined
var
The var
keyword in JavaScript is used to declare variables that are function-scoped or globally-scoped, depending on where they are declared. Here are some key points about var
:
Characteristics of var
-
Function Scope: Variables declared with
var
are scoped to the function in which they are declared. If declared outside any function, they are globally scoped.
function example() {
var message = "Hello!";
console.log(message); // "Hello!"
}
console.log(message); // ReferenceError: message is not defined
-
Hoisting:
var
declarations are hoisted to the top of their scope, meaning the declaration is processed before any code is executed. However, the initialization is not hoisted.
console.log(x); // undefined
var x = 5;
-
Re-declaration and Reassignment: Variables declared with
var
can be re-declared and reassigned within the same scope.
var count = 1;
var count = 2; // This is allowed
count = 3; // This is also allowed
Example Usage
var name = "Alice";
name = "Bob"; // This is fine
function greet() {
var greeting = "Hello!";
console.log(greeting); // "Hello!"
}
greet();
// console.log(greeting); // ReferenceError: greeting is not defined
const
The const
keyword in JavaScript is used to declare variables that are block-scoped and cannot be reassigned. Here are some important points about const
:
Characteristics of const
-
Block Scope: Similar to
let
,const
variables are confined to the block in which they are declared.
if (true) {
const greeting = "Hello!";
console.log(greeting); // "Hello!"
}
console.log(greeting); // ReferenceError: greeting is not defined
-
No Reassignment: Once a
const
variable is assigned a value, it cannot be reassigned. However, if the variable holds an object or array, the contents of the object or array can be modified.
const number = 10;
number = 20; // TypeError: Assignment to constant variable.
const person = { name: "Alice" };
person.name = "Bob"; // This is allowed
console.log(person.name); // "Bob"
-
Must Be Initialized:
const
variables must be initialized at the time of declaration.
const age; // SyntaxError: Missing initializer in const declaration
Example Usage
const birthYear = 1990;
console.log(birthYear); // 1990
const colors = ["red", "green", "blue"];
colors.push("yellow"); // This is allowed
console.log(colors); // ["red", "green", "blue", "yellow"]
Comparison of var
, let
, and const
var
- Scope: Function-scoped.
- Hoisting: Declarations are hoisted to the top of their scope, but not the initializations.
- Re-declaration: Can be re-declared within the same scope.
- Reassignment: Can be reassigned.
- Example:
var x = 10;
var x = 20; // Allowed
x = 30; // Allowed
let
- Scope: Block-scoped.
- Hoisting: Declarations are hoisted but not initialized, leading to a "temporal dead zone" until the declaration is encountered.
- Re-declaration: Cannot be re-declared within the same scope.
- Reassignment: Can be reassigned.
- Example:
let y = 10;
// let y = 20; // SyntaxError: Identifier 'y' has already been declared
y = 30; // Allowed
const
- Scope: Block-scoped.
- Hoisting: Declarations are hoisted but not initialized, leading to a "temporal dead zone" until the declaration is encountered.
- Re-declaration: Cannot be re-declared within the same scope.
- Reassignment: Cannot be reassigned. However, if the variable holds an object or array, the contents can be modified.
- Example:
const z = 10;
// z = 20; // TypeError: Assignment to constant variable.
const obj = { name: "Alice" };
obj.name = "Bob"; // Allowed
Summary
-
Scope:
var
is function-scoped, whilelet
andconst
are block-scoped. -
Hoisting: All are hoisted, but
let
andconst
are not initialized until their declaration. -
Re-declaration:
var
can be re-declared, butlet
andconst
cannot. -
Reassignment:
var
andlet
can be reassigned, butconst
cannot be reassigned. In JavaScript, variables can be classified as either global or local based on their scope. Here's a breakdown of each:
Global Variables
- Definition: Variables declared outside any function or block are global variables. They are accessible from anywhere in the code.
- Scope: Global scope.
- Example:
var globalVar = "I am global";
function showGlobalVar() {
console.log(globalVar); // "I am global"
}
showGlobalVar();
console.log(globalVar); // "I am global"
Local Variables
- Definition: Variables declared within a function or block are local variables. They are only accessible within that function or block.
- Scope: Function or block scope.
- Example:
function showLocalVar() {
var localVar = "I am local";
console.log(localVar); // "I am local"
}
showLocalVar();
// console.log(localVar); // ReferenceError: localVar is not defined
Key Differences
- Scope: Global variables have a global scope, while local variables have a function or block scope.
- Lifetime: Global variables exist for the duration of the page's life. Local variables exist only during the execution of the function or block in which they are declared.
- Accessibility: Global variables can be accessed from anywhere in the code. Local variables can only be accessed within the function or block they are declared in.
Example with let
and const
Using let
and const
for block-scoped local variables:
if (true) {
let blockVar = "I am block-scoped";
const blockConst = "I am also block-scoped";
console.log(blockVar); // "I am block-scoped"
console.log(blockConst); // "I am also block-scoped"
}
// console.log(blockVar); // ReferenceError: blockVar is not defined
// console.log(blockConst); // ReferenceError: blockConst is not defined
Accessing Variables from Another File
To access variables from another file in JavaScript, you can use the module system provided by Node.js or ES6 modules. Here are the steps for both methods:
Using Node.js (CommonJS) Modules
- Export Variables: In the source file, export the variables you want to access.
// sourceFile.js
const greeting = "Hello, World!";
const number = 42;
module.exports = { greeting, number };
-
Import Variables: In the target file, import the variables using
require
.
// targetFile.js
const { greeting, number } = require('./sourceFile');
console.log(greeting); // "Hello, World!"
console.log(number); // 42
Using ES6 Modules
-
Export Variables: In the source file, export the variables using
export
.
// sourceFile.js
export const greeting = "Hello, World!";
export const number = 42;
-
Import Variables: In the target file, import the variables using
import
.
// targetFile.js
import { greeting, number } from './sourceFile.js';
console.log(greeting); // "Hello, World!"
console.log(number); // 42
Example with Default Export
If you want to export a single value as the default export:
- Export Default:
// sourceFile.js
const greeting = "Hello, World!";
export default greeting;
- Import Default:
// targetFile.js
import greeting from './sourceFile.js';
console.log(greeting); // "Hello, World!"
Note
- Ensure the file paths are correct when using
require
orimport
. - For ES6 modules, make sure your environment supports ES6 module syntax or use a bundler like Webpack or a transpiler like Babel.
JavaScript Data Types
In JavaScript, data types are categorized into two main types: primitive and non-primitive (or reference) types. Here's an overview of each:
Primitive Data Types
- String: Represents textual data.
let name = "Alice";
- Number: Represents both integer and floating-point numbers.
let age = 30;
let price = 19.99;
-
Boolean: Represents logical values:
true
orfalse
.
let isActive = true;
- Undefined: Represents a variable that has been declared but not assigned a value.
let x;
console.log(x); // undefined
- Null: Represents the intentional absence of any object value.
let y = null;
- Symbol: Represents a unique and immutable value, often used as object property keys.
let sym = Symbol("unique");
- BigInt: Represents integers with arbitrary precision.
let bigInt = 1234567890123456789012345678901234567890n;
Non-Primitive (Reference) Data Types
- Object: Represents a collection of key-value pairs.
let person = {
name: "Alice",
age: 30
};
- Array: Represents an ordered list of values.
let colors = ["red", "green", "blue"];
- Function: Represents a block of code designed to perform a particular task.
function greet() {
console.log("Hello!");
}
Type Checking
You can check the type of a variable using the typeof
operator:
console.log(typeof name); // "string"
console.log(typeof age); // "number"
console.log(typeof isActive); // "boolean"
console.log(typeof x); // "undefined"
console.log(typeof y); // "object" (null is considered an object due to a historical bug)
console.log(typeof sym); // "symbol"
console.log(typeof bigInt); // "bigint"
console.log(typeof person); // "object"
console.log(typeof colors); // "object"
console.log(typeof greet); // "function"
Type Conversion
Type conversion in JavaScript refers to changing a value from one data type to another. There are two types of type conversion: implicit (automatic) and explicit (manual).
Implicit Type Conversion (Type Coercion)
JavaScript automatically converts data types when performing operations involving different types.
Examples:
- String Concatenation:
let result = "The answer is " + 42; // "The answer is 42"
- Numeric Conversion:
let sum = "5" - 2; // 3 (string "5" is converted to number 5)
let product = "5" * 2; // 10 (string "5" is converted to number 5)
- Boolean Conversion:
let isTrue = !!"non-empty string"; // true
let isFalse = !!0; // false
Explicit Type Conversion
You manually convert data types using built-in functions or operators.
Examples:
- String Conversion:
let num = 42;
let str = String(num); // "42"
let str2 = num.toString(); // "42"
- Number Conversion:
let str = "42";
let num = Number(str); // 42
let num2 = parseInt(str); // 42
let num3 = parseFloat("42.5"); // 42.5
- Boolean Conversion:
let str = "hello";
let bool = Boolean(str); // true
let bool2 = !!str; // true
Examples in Practice
// Implicit Conversion
console.log("5" + 2); // "52" (string concatenation)
console.log("5" - 2); // 3 (numeric conversion)
console.log("5" * 2); // 10 (numeric conversion)
console.log("5" / 2); // 2.5 (numeric conversion)
// Explicit Conversion
let str = "123";
let num = Number(str); // 123
let bool = Boolean(str); // true
console.log(num); // 123
console.log(bool); // true
let num2 = 456;
let str2 = String(num2); // "456"
console.log(str2); // "456"
Hoisting is a JavaScript mechanism where variable and function declarations are moved to the top of their containing scope during the compile phase. This means you can use variables and functions before they are declared in the code. However, only the declarations are hoisted, not the initializations.
Variable Hoisting
-
var
: Declarations are hoisted to the top of their function scope, but the initialization remains in place.
console.log(x); // undefined
var x = 5;
console.log(x); // 5
-
let
andconst
: Declarations are hoisted to the top of their block scope, but they are not initialized. Accessing them before the declaration results in aReferenceError
due to the "temporal dead zone."
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
console.log(z); // ReferenceError: Cannot access 'z' before initialization
const z = 15;
Function Hoisting
- Function Declarations: Entire function declarations are hoisted to the top of their scope, so you can call the function before its declaration.
greet(); // "Hello!"
function greet() {
console.log("Hello!");
}
- Function Expressions: Only the variable declaration is hoisted, not the function assignment. This means you cannot call the function before its assignment.
console.log(sayHello); // undefined
// sayHello(); // TypeError: sayHello is not a function
var sayHello = function() {
console.log("Hello!");
};
Example
Here's an example demonstrating hoisting with var
, let
, const
, and function declarations:
console.log(a); // undefined
var a = 1;
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 2;
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 3;
foo(); // "foo"
function foo() {
console.log("foo");
}
// bar(); // TypeError: bar is not a function
var bar = function() {
console.log("bar");
};
Summary
-
var
: Declarations are hoisted, but initializations are not. -
let
andconst
: Declarations are hoisted, but not initialized, leading to a "temporal dead zone." - Function Declarations: Entire declarations are hoisted.
- Function Expressions: Only the variable declaration is hoisted, not the function assignment.