Core JavaScript Syntax and Execution Fundamentals
JavaScript operates through three primary architectural layers: the ECMAScript core language specification, the Document Object Model (DOM) for manipulating webpage structure and content, and the Browser Object Model (BOM) for interacting with the browser window, navigation, and history. Scripts integrate into HTML documents via inline execution blocks or external file references:
<!-- Inline execution -->
<script>
console.log("Inline script loaded");
</script>
<!-- External module reference -->
<script src="app_logic.js"></script>
Variable Declarations and Scoping
Comments utilize // for single-line ennotations and /* */ for multi-line blocks. Statements typically terminate with semicolons, though Automatic Semicolon Insertion (ASI) often handles omission. Identifiers follow camelCase conventions (e.g., userProfile, strEmail).
Declaration keywords dictate scope, hoisting behavior, and reassignment rules:
var: Function-scoped, permits redeclaration, and initializes asundefinedprior to assignment.let: Block-scoped, prohibits redeclaration within the same lexical environment, and throws aReferenceErrorif accessed before initialization.
let primaryColor = "blue";
let secondaryColor = "gray", maxRetries = 3;
Hoisting moves var declarations to the top of their execution context during the compilation phase, but assignments remain in place. Accessing a hoisted variable before its assignment yields undefined.
console.log(counter); // undefined
var counter = 10;
Strict mode ("use strict";) eliminates silent failures, prevents accidental globals, and enforces explicit declarations. It applies globally or per-function scope.
"use strict";
// totalScore = 95; // Throws ReferenceError: totalScore is not defined
function calculateMetric() {
"use strict";
// let result = baseValue * 2; // Throws ReferenceError if baseValue is undeclared
}
Constants and Memory References
The const keyword requires immediate initialization and prevents identifier reassignment. Like let, it enforces a Temporal Dead Zone (TDZ), blocking access before the declaration line executes.
const API_ENDPOINT = "https://api.example.com";
// API_ENDPOINT = "new"; // TypeError: Assignment to constant variable
if (true) {
// console.log(LOCAL_CONFIG); // ReferenceError due to TDZ
const LOCAL_CONFIG = { timeout: 5000 };
}
const guarantees reference immutability, not deep value immutability. Primitive values remain fixed, but object properties and array elements can still be mutated because the memory pointer itself remains constant.
const settings = { theme: "dark" };
settings.theme = "light"; // Valid: mutates the object property, not the reference
Type System and Conversion
Primitives include number, string, boolean, null, undefined, symbol, and bigint. The typeof operator identifies most primitives but historically returns "object" for null and arrays.
undefined: Default state for uninitialized variables or functions lacking a explicitreturn.null: Explicit assignment indicating the intentional absence of an object reference.
Implicit coercion occurs during mixed-type operations:
42 + "px" // "42px"
15 + true // 16
false + "mode" // "falsemode"
Explicit parsing handles string-to-number conversion:
parseInt("42.9rem") // 42
parseInt("xyz9") // NaN
parseFloat("3.14rad") // 3.14
eval("10 * 5") // 50 (Note: generally discouraged for security and performance)
Operators and Comparisons
Arithmetic operators include +, -, *, /, %, ++, and --. Post-increment (i++) returns the original value before incrementing, while pre-increment (++i) returns the updated value.
Equality checks differentiate between loose (==) and strict (===) comparison. Loose equality triggers type coercion:
booleanvsnumber: boolean converts to number (true→ 1,false→ 0).numbervsstring: string converts to number.objectvsprimitive: object converts viavalueOf()ortoString().
5 == "5" // true
0 == false // true
null == undefined // true
5 === "5" // false (strict type and value check)
Relational operators compare strings via UTF-16 code unit values. Non-numeric strings compared to numbers result in false after NaN coercion.
"10" < "2" // true (lexicographical comparison)
"A" < "a" // true
"5" < 3 // false
"abc" < 10 // false (NaN comparison always yields false)
Control Flow Structures
Conditional branching and iteration follow standard C-style syntax.
let temperature = 28;
if (temperature > 30) {
console.log("Hot");
} else if (temperature > 20) {
console.log("Warm");
} else {
console.log("Cool");
}
Switch statements match exact values and require break to prevent fallthrough execution.
let statusCode = 404;
switch (statusCode) {
case 200:
console.log("OK");
break;
case 404:
console.log("Not Found");
break;
default:
console.log("Unknown Status");
}
Loops handle iteration. The for...in construct enumerates object keys and is generallly unsuitable for arrays due to prototype chain enumeration and non-guaranteed order.
for (let idx = 0; idx < 5; idx++) {
console.log(idx);
}
let cursor = 0;
while (cursor < 3) {
console.log(cursor);
cursor++;
}
Ternary operators provide concise conditional assignment. Nested ternaries should be structured carefully to maintain readability.
let limit = 100;
let current = 85;
let status = current > limit ? "Exceeded" : "Within Range";
let a = 5, b = 10;
let result = a > b ? a : (b === 10 ? a + b : b); // result evaluates to 15