Labs ICT
⭐ Pro Login

Syntax

JavaScript syntax defines the rules for writing valid JavaScript code. Understanding syntax is fundamental to writing error-free programs.

In this tutorial, we'll explore JavaScript's syntax rules, from basic statements to complex expressions, and common syntax errors to avoid.

Basic Syntax Elements

JavaScript syntax consists of various elements that combine to form valid programs and expressions.

Statements and Expressions

// Statements - Instructions that perform actions
// Declaration statements
const name = 'John'; // Variable declaration
let age = 30; // Variable declaration
var oldVariable = 'value'; // Old-style variable declaration

// Assignment statements
name = 'Jane'; // Variable assignment
age = age + 1; // Expression assignment

// Control statements
if (age >= 18) {
  console.log('Adult');
} // Conditional statement

for (let i = 0; i < 10; i++) {
  console.log(i);
} // Loop statement

// Expressions - Code that evaluates to a value
const result = 5 + 3 * 2; // Arithmetic expression
const isAdult = age >= 18; // Comparison expression
const message = `Hello, ${name}!`; // Template literal expression

// Function expressions
const add = function(a, b) { return a + b; }; // Function expression
const multiply = (a, b) => a * b; // Arrow function expression

// Object expressions
const person = {
  name: 'John',
  age: 30,
  greet: function() {
    return `Hello, I'm ${this.name}`;
  }
}; // Object literal expression

// Array expressions
const numbers = [1, 2, 3, 4, 5]; // Array literal expression
const mixed = [1, 'two', true, null]; // Mixed type array expression

// Regular expression expressions
const pattern = /hello/g; // Regular expression literal
const dynamicPattern = new RegExp('hello', 'g'); // RegExp constructor expression

Comments and Whitespace

// Single-line comments
const x = 5; // This is a single-line comment
const y = 10; // Another single-line comment

// Multi-line comments
/*
  This is a multi-line comment
  It can span multiple lines
  Useful for longer explanations
*/
const z = 15;

// Inline comments
const result = x + y; // Add x and y
console.log(result); // Display the result

// Whitespace and formatting
const formatted = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3'
}; // Properly formatted object

// Whitespace rules
const a = 1 + 2; // Spaces around operators
const b = 1+2; // No spaces (valid but less readable)
const c = 1 + 2; // Recommended spacing

// Line breaks
const longString = 'This is a very long string that ' +
                  'spans multiple lines for ' +
                  'better readability';

// Indentation
if (condition) {
  // Indented code block
  console.log('Condition is true');
} else {
  // Consistent indentation
  console.log('Condition is false');
}

// Semicolons
const statement1 = 'value1'; // Statement with semicolon
const statement2 = 'value2' // Statement without semicolon (ASI handles it)

Identifiers and Naming

// Valid identifiers
const userName = 'john_doe';
const $element = document.getElementById('myElement');
const _private = 'private value';
const camelCase = 'camelCaseVariable';
const PascalCase = 'PascalCaseClass';
const snake_case = 'snake_case_variable';

// Valid identifier rules
// - Can contain letters, numbers, underscores, and dollar signs
// - Cannot start with a number
// - Cannot be a reserved word
// - Case-sensitive

// Valid examples
const valid1 = 'variable';
const valid2 = 'variable_name';
const valid3 = 'variableName';
const valid4 = '$variable';
const valid5 = '_variable';
const valid6 = 'variable123';

// Invalid examples
// const 1invalid = 'value'; // Cannot start with number
// const invalid-name = 'value'; // Hyphen not allowed
// const invalid.name = 'value'; // Dot not allowed
// const if = 'value'; // Reserved word
// const class = 'value'; // Reserved word

// Naming conventions
// Variables and functions: camelCase
const userName = 'john';
const getUserData = () => { /* ... */ };

// Classes: PascalCase
class UserService {
  constructor() {
    // ...
  }
}

// Constants: UPPER_SNAKE_CASE
const API_BASE_URL = 'https://api.example.com';
const MAX_RETRY_COUNT = 3;

// Private variables: underscore prefix
const _privateVariable = 'private value';
const _internalMethod = () => { /* ... */ };

// Unicode identifiers
const пСрСмСнная = 'Russian variable';
const ε˜ι‡ = 'Chinese variable';
const Ω…Ψͺغير = 'Arabic variable';

// Escape sequences in identifiers
const invalid\u0020Name = 'invalid'; // Contains Unicode space
const valid$Name = 'valid'; // Dollar sign is valid

Data Types and Literals

JavaScript supports various data types, each with specific syntax rules for literal values.

Primitive Types

// String literals
const singleQuote = 'Hello, World!';
const doubleQuote = "Hello, World!";
const templateLiteral = `Hello, ${name}!`;
const multiLine = `This is a
multi-line
string`;

// String escape sequences
const withQuotes = 'He said "Hello"';
const withNewline = 'Line 1\nLine 2';
const withTab = 'Column 1\tColumn 2';
const withBackslash = 'Path\\to\\file';
const withUnicode = '\u00A9 Copyright symbol';

// Number literals
const integer = 42;
const negative = -17;
const floating = 3.14159;
const scientific = 1.23e-4;
const hex = 0xFF;
const octal = 0755;
const binary = 0b1010;
const bigInt = 9007199254740991n;

// Boolean literals
const isTrue = true;
const isFalse = false;

// Null literal
const emptyValue = null;

// Undefined literal
const notDefined = undefined;

// Symbol literals
const uniqueSymbol = Symbol('description');
const globalSymbol = Symbol.for('global');

Object Literals

// Empty object literal
const emptyObject = {};

// Object with properties
const person = {
  name: 'John Doe',
  age: 30,
  email: 'john@example.com'
};

// Object with methods
const calculator = {
  add: function(a, b) {
    return a + b;
  },
  
  subtract: (a, b) => a - b,
  
  multiply(a, b) {
    return a * b;
  },
  
  divide(a, b) {
    return a / b;
  }
};

// Object with computed property names
const propertyName = 'dynamic';
const dynamicObject = {
  [propertyName]: 'dynamic value',
  ['computed_' + 'property']: 'computed value'
};

// Object with shorthand properties
const name = 'John';
const age = 30;
const shorthandObject = {
  name, // Same as name: name
  age,  // Same as age: age
  greet() {
    return `Hello, ${this.name}!`;
  }
};

// Object with getter and setter
const user = {
  _name: 'John',
  
  get name() {
    return this._name;
  },
  
  set name(newName) {
    if (typeof newName === 'string' && newName.length > 0) {
      this._name = newName;
    }
  }
};

// Object with spread syntax
const baseObject = { a: 1, b: 2 };
const extendedObject = {
  ...baseObject,
  c: 3,
  d: 4
};

Array Literals

// Empty array literal
const emptyArray = [];

// Array with elements
const numbers = [1, 2, 3, 4, 5];
const mixedTypes = [1, 'two', true, null, undefined];
const nested = [[1, 2], [3, 4], [5, 6]];

// Array with trailing comma
const withComma = [1, 2, 3,]; // Valid in JavaScript

// Array with holes
const sparseArray = [1, , 3, , 5]; // Creates sparse array

// Array with spread syntax
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const combined = [...array1, ...array2]; // [1, 2, 3, 4, 5, 6]

// Array with computed elements
const index = 0;
const dynamicArray = [
  `element_${index}`,
  `element_${index + 1}`,
  `element_${index + 2}`
];

// Array destructuring
const [first, second, third] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(third); // 3

// Array with rest operator
const [head, ...tail] = [1, 2, 3, 4, 5];
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]

Control Structures

Control structures direct program flow and include conditional statements, loops, and exception handling.

Conditional Statements

// if statement
if (condition) {
  // Code to execute if condition is true
  console.log('Condition is true');
}

// if...else statement
if (age >= 18) {
  console.log('Adult');
} else {
  console.log('Minor');
}

// if...else if...else statement
if (score >= 90) {
  grade = 'A';
} else if (score >= 80) {
  grade = 'B';
} else if (score >= 70) {
  grade = 'C';
} else {
  grade = 'D';
}

// Nested if statements
if (condition1) {
  if (condition2) {
    // Nested condition
    console.log('Both conditions are true');
  }
}

// switch statement
switch (expression) {
  case value1:
    // Code for value1
    console.log('Value 1');
    break;
  case value2:
    // Code for value2
    console.log('Value 2');
    break;
  default:
    // Default case
    console.log('Default case');
}

// switch with multiple cases
switch (day) {
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    console.log('Weekday');
    break;
  case 6:
  case 7:
    console.log('Weekend');
    break;
  default:
    console.log('Invalid day');
}

// switch with fall-through
switch (number) {
  case 1:
    console.log('One');
    // Fall through to next case
  case 2:
    console.log('Two');
    break;
}

// Ternary operator (conditional expression)
const result = condition ? valueIfTrue : valueIfFalse;
const message = age >= 18 ? 'Adult' : 'Minor';

// Nested ternary operators
const finalGrade = score >= 90 ? 'A' : 
                  score >= 80 ? 'B' : 
                  score >= 70 ? 'C' : 'D';

Loop Statements

// for loop
for (initialization; condition; increment) {
  // Loop body
  console.log(i);
}

for (let i = 0; i < 10; i++) {
  console.log(i);
}

// for...in loop (object properties)
const person = {
  name: 'John',
  age: 30,
  email: 'john@example.com'
};

for (const property in person) {
  if (person.hasOwnProperty(property)) {
    console.log(`${property}: ${person[property]}`);
  }
}

// for...of loop (iterable values)
const colors = ['red', 'green', 'blue'];

for (const color of colors) {
  console.log(color);
}

// for...of loop with destructuring
const users = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' }
];

for (const { id, name } of users) {
  console.log(`User ${id}: ${name}`);
}

// while loop
let count = 0;
while (count < 5) {
  console.log(count);
  count++;
}

// do...while loop
let i = 0;
do {
  console.log(i);
  i++;
} while (i < 5);

// Infinite loop with break
while (true) {
  console.log('Processing...');
  if (someCondition) {
    break;
  }
}

// Labeled loops
outer: for (let i = 0; i < 3; i++) {
  inner: for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break outer; // Break out of outer loop
    }
    console.log(`i: ${i}, j: ${j}`);
  }
}

// continue statement
for (let i = 0; i < 10; i++) {
  if (i % 2 === 0) {
    continue; // Skip even numbers
  }
  console.log(i); // Only odd numbers
}

Exception Handling

// try...catch statement
try {
  // Code that might throw an error
  const result = riskyOperation();
  console.log('Operation succeeded:', result);
} catch (error) {
  // Error handling code
  console.error('Operation failed:', error.message);
}

// try...catch...finally statement
try {
  const data = fetchData();
  processData(data);
} catch (error) {
  console.error('Error:', error.message);
} finally {
  // Cleanup code (always executed)
  console.log('Cleanup completed');
}

// try...catch with specific error types
try {
  const result = divideNumbers(10, 0);
} catch (error) {
  if (error instanceof TypeError) {
    console.error('Type error:', error.message);
  } else if (error instanceof RangeError) {
    console.error('Range error:', error.message);
  } else {
    console.error('Unknown error:', error.message);
  }
}

// throw statement
function validateAge(age) {
  if (typeof age !== 'number') {
    throw new TypeError('Age must be a number');
  }
  
  if (age < 0) {
    throw new RangeError('Age cannot be negative');
  }
  
  if (age > 150) {
    throw new RangeError('Age cannot exceed 150');
  }
  
  return `Valid age: ${age}`;
}

// try...catch with throw
try {
  validateAge(-5);
} catch (error) {
  console.error('Validation error:', error.message);
}

// Multiple catch blocks
try {
  const result = complexOperation();
} catch (syntaxError) {
  console.error('Syntax error:', syntaxError.message);
} catch (typeError) {
  console.error('Type error:', typeError.message);
} catch (error) {
  console.error('Unknown error:', error.message);
}

// Nested try...catch
try {
  try {
    const innerResult = innerOperation();
    console.log('Inner operation succeeded:', innerResult);
  } catch (innerError) {
    console.error('Inner operation failed:', innerError.message);
    throw innerError; // Re-throw to outer catch
  }
} catch (outerError) {
  console.error('Outer operation failed:', outerError.message);
}

Functions and Classes

Functions and classes are fundamental building blocks in JavaScript, each with specific syntax rules.

Function Syntax

// Function declaration
function functionName(param1, param2) {
  // Function body
  return param1 + param2;
}

// Function with default parameters
function greet(name = 'Guest') {
  return `Hello, ${name}!`;
}

// Function with rest parameters
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

// Function expression
const add = function(a, b) {
  return a + b;
};

// Arrow function
const multiply = (a, b) => a * b;

// Arrow function with single parameter
const square = x => x * x;

// Arrow function with no parameters
const getRandom = () => Math.random();

// Arrow function with block body
const complexOperation = (a, b) => {
  const result = a * b;
  return result + 1;
};

// Function with destructuring parameters
function processUser({ name, age, email }) {
  return `User: ${name}, Age: ${age}, Email: ${email}`;
}

// Function with array destructuring
function getFirstAndLast([first, ...middle, last]) {
  return { first, middle, last };
}

// Immediately Invoked Function Expression (IIFE)
(function() {
  console.log('IIFE executed immediately');
})();

// IIFE with parameters
(function(name) {
  console.log(`Hello, ${name}!`);
})('John');

// Generator function
function* numberGenerator() {
  let i = 1;
  while (i <= 10) {
    yield i;
    i++;
  }
}

// Async function
async function fetchData(url) {
  try {
    const response = await fetch(url);
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Fetch error:', error.message);
    throw error;
  }
}

Class Syntax

// Class declaration
class ClassName {
  constructor(param1, param2) {
    this.property1 = param1;
    this.property2 = param2;
  }
  
  method1() {
    return this.property1;
  }
  
  method2() {
    return this.property2;
  }
}

// Class with properties
class Person {
  name = 'Default Name';
  age = 0;
  
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

// Class with methods
class Calculator {
  constructor() {
    this.result = 0;
  }
  
  add(number) {
    this.result += number;
    return this.result;
  }
  
  subtract(number) {
    this.result -= number;
    return this.result;
  }
  
  multiply(number) {
    this.result *= number;
    return this.result;
  }
  
  divide(number) {
    this.result /= number;
    return this.result;
  }
}

// Class with getters and setters
class User {
  #name; // Private field (ES2022)
  
  constructor(name) {
    this.#name = name;
  }
  
  get name() {
    return this.#name;
  }
  
  set name(newName) {
    if (typeof newName === 'string' && newName.length > 0) {
      this.#name = newName;
    }
  }
}

// Class with static methods
class MathUtils {
  static add(a, b) {
    return a + b;
  }
  
  static multiply(a, b) {
    return a * b;
  }
  
  static divide(a, b) {
    if (b === 0) {
      throw new Error('Division by zero');
    }
    return a / b;
  }
}

// Class inheritance
class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    return `${this.name} makes a sound`;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Call parent constructor
    this.breed = breed;
  }
  
  speak() {
    return `${this.name} barks`;
  }
  
  getDetails() {
    return `${this.speak()} (${this.breed})`;
  }
}

// Class with static properties
class Config {
  static API_URL = 'https://api.example.com';
  static VERSION = '1.0.0';
  
  static getConfig() {
    return {
      url: this.API_URL,
      version: this.VERSION
    };
  }
}

// Class expression
const MyClass = class {
  constructor(value) {
    this.value = value;
  }
  
  getValue() {
    return this.value;
  }
};

Operators and Expressions

JavaScript operators combine values to form expressions, following specific precedence and associativity rules.

Arithmetic Operators

// Addition
const sum = 5 + 3; // 8

// Subtraction
const difference = 10 - 4; // 6

// Multiplication
const product = 6 * 7; // 42

// Division
const quotient = 15 / 3; // 5

// Modulo
const remainder = 17 % 5; // 2

// Exponentiation
const power = 2 ** 3; // 8

// Unary plus
const positive = +5; // 5

// Unary minus
const negative = -5; // -5

// Increment
let count = 5;
count++; // 6
++count; // 7

// Decrement
count--; // 6
--count; // 5

// Complex arithmetic expressions
const result = (a + b) * c - d / e + f ** g;

Comparison Operators

// Equality (abstract)
console.log(5 == '5'); // true (type coercion)
console.log(5 === 5); // true (strict equality)
console.log(5 !== '5'); // false (strict inequality)
console.log(5 != '5'); // false (abstract inequality)

// Relational operators
console.log(5 > 3); // true
console.log(5 >= 5); // true
console.log(5 < 3); // false
console.log(5 <= 5); // true

// Complex comparisons
const isValid = (age >= 18 && age <= 65) && (hasLicense || hasPermit);

// Comparison with different types
console.log(null == undefined); // true
console.log(null === undefined); // false
console.log('5' == 5); // true
console.log('5' === 5); // false

Logical Operators

// Logical AND (&&)
const result1 = true && true; // true
const result2 = true && false; // false
const result3 = false && true; // false
const result4 = false && false; // false

// Short-circuit evaluation
const user = { name: 'John', age: 30 };
const greeting = user && `Hello, ${user.name}!`; // 'Hello, John!'

// Logical OR (||)
const result5 = true || false; // true
const result6 = true || true; // true
const result7 = false || true; // true
const result8 = false || false; // false

// Default values with OR
const name = userName || 'Guest';
const timeout = userTimeout || 5000;

// Logical NOT (!)
const result9 = !true; // false
const result10 = !false; // true
const result11 = !0; // true
const result12 = !'hello'; // false

// Complex logical expressions
const canVote = (age >= 18 && hasRegistration) || (isCitizen && age >= 16);
const isAdmin = (role === 'admin') || (role === 'superadmin') || hasElevatedPermissions;

Assignment Operators

// Simple assignment
let x = 5;

// Addition assignment
x += 3; // x = x + 3

// Subtraction assignment
x -= 2; // x = x - 2

// Multiplication assignment
x *= 4; // x = x * 4

// Division assignment
x /= 2; // x = x / 2

// Modulo assignment
x %= 3; // x = x % 3

// Exponentiation assignment
x **= 2; // x = x ** 2

// Left shift assignment
x <<= 1; // x = x << 1

// Right shift assignment
x >>= 1; // x = x >> 1

// Bitwise AND assignment
x &= 3; // x = x & 3

// Bitwise OR assignment
x |= 5; // x = x | 5

// Bitwise XOR assignment
x ^= 2; // x = x ^ 2

// Destructuring assignment
const { name, age } = person;
const [first, second, third] = [1, 2, 3];

// Multiple assignment
let a, b, c;
a = b = c = 5; // All variables get value 5

Modern JavaScript Syntax

Modern JavaScript (ES6+) introduces new syntax features that make code more expressive and readable.

Template Literals

// Basic template literal
const name = 'John';
const greeting = `Hello, ${name}!`;

// Multi-line template literal
const message = `This is a
multi-line
message with ${name}`;

// Template literal with expressions
const price = 100;
const tax = 0.08;
const total = `Total: $${price * (1 + tax)}`;

// Tagged template literals
function highlight(strings, ...values) {
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `${values[i]}` : '');
  }, '');
}

const highlighted = highlight`Hello ${name}, welcome to our site!`;

// Raw template literals
function raw(strings, ...values) {
  return strings.raw.reduce((result, str, i) => {
    return result + str + (values[i] || '');
  }, '');
}

const rawString = raw`Hello\nWorld`; // Preserves backslashes

Destructuring

// Object destructuring
const person = {
  name: 'John',
  age: 30,
  email: 'john@example.com',
  city: 'New York'
};

// Basic destructuring
const { name, age } = person;

// Destructuring with renaming
const { name: userName, age: userAge } = person;

// Destructuring with default values
const { name = 'Guest', age = 0 } = person;

// Destructuring with rest operator
const { name, age, ...rest } = person;

// Nested destructuring
const user = {
  personal: {
    name: 'John',
    age: 30
  },
  contact: {
    email: 'john@example.com',
    phone: '555-1234'
  }
};

const { personal: { name, age }, contact: { email } } = user;

// Array destructuring
const colors = ['red', 'green', 'blue', 'yellow'];

// Basic array destructuring
const [first, second, third] = colors;

// Destructuring with default values
const [a = 1, b = 2, c = 3] = colors;

// Destructuring with rest operator
const [primary, ...secondary] = colors;

// Skipping elements
const [, , third, fourth] = colors;

// Array destructuring with default
const [x = 0, y = 0] = [];

// Function parameter destructuring
function processUser({ name, age, email }) {
  return `User: ${name}, Age: ${age}, Email: ${email}`;
}

function getCoordinates([x, y]) {
  return { x, y };
}

// Mixed destructuring
const data = {
  user: {
    name: 'John',
    details: ['admin', 'user']
  },
  settings: ['theme', 'language']
};

const {
  user: { name, details: [role, type] },
  settings: [theme]
} = data;

Spread and Rest

// Spread operator with arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

// Spread operator with objects
const base = { a: 1, b: 2 };
const extension = { c: 3, d: 4 };
const merged = { ...base, ...extension }; // { a: 1, b: 2, c: 3, d: 4 }

// Spread with function calls
const numbers = [1, 2, 3, 4, 5];
const max = Math.max(...numbers); // 5

// Spread with array literals
const newArray = [...existingArray, newItem];

// Spread with object literals
const newObject = { ...existingObject, newProperty: value };

// Rest operator in function parameters
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

// Rest operator in array destructuring
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [2, 3, 4, 5]

// Rest operator in object destructuring
const { a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4, e: 5 };
console.log(a); // 1
console.log(b); // 2
console.log(rest); // { c: 3, d: 4, e: 5 }

// Rest with arrow functions
const concatenate = (...strings) => strings.join('');

// Combining spread and rest
function processArray(...items) {
  const [first, ...rest] = items;
  return {
    first,
    rest: [...rest, first] // Move first to end
  };
}

Optional Chaining

// Optional chaining (?.)
const user = {
  name: 'John',
  address: {
    street: '123 Main St',
    city: 'New York'
  }
};

// Safe property access
const street = user?.address?.street; // '123 Main St'
const zip = user?.address?.zip; // undefined (no error)

// Optional chaining with method calls
const result = user?.getName?.(); // Calls getName if user exists

// Optional chaining with array access
const items = [null, { value: 42 }];
const value = items[1]?.value; // 42

// Optional chaining with function calls
const getValue = (obj) => obj?.value ?? 'default';

// Nullish coalescing operator (??)
const name = user?.name ?? 'Anonymous';
const age = user?.age ?? 0;

// Combining optional chaining and nullish coalescing
const displayName = user?.profile?.name ?? 'Guest User';
const timeout = settings?.timeout ?? 5000;

// Optional chaining with method calls and parameters
const result = obj?.method?.(param1, param2);

// Optional chaining assignment
user?.address?.zip = '10001'; // Only assigns if path exists

Common Syntax Errors

Understanding common syntax errors helps identify and fix issues quickly in JavaScript code.

Bracket and Parenthesis Errors

// Mismatched brackets
// Error: Missing closing bracket
const obj = {
  key1: 'value1',
  key2: 'value2'
}; // Missing closing brace

// Error: Extra bracket
const arr = [1, 2, 3]]; // Extra closing bracket

// Error: Mismatched brackets
const mixed = [1, 2, 3}; // Square bracket with curly brace

// Mismatched parentheses
// Error: Missing closing parenthesis
if (condition {
  console.log('true');
} // Missing closing parenthesis

// Error: Extra parenthesis
if ((condition))) {
  console.log('true');
} // Extra closing parenthesis

// Correct examples
const correctObj = {
  key1: 'value1',
  key2: 'value2'
};

const correctArr = [1, 2, 3];

if (condition) {
  console.log('true');
}

// Nested brackets
const nested = {
  outer: {
    inner: {
      value: 'nested'
    }
  }
};

// Complex expressions with brackets
const result = (a + b) * (c - d) / (e + f);

Semicolon and Comma Errors

// Missing semicolons
// Error: Automatic semicolon insertion issues
const a = 1
const b = 2
return a + b // ASI might insert semicolon in wrong place

// Correct usage
const a = 1;
const b = 2;
return a + b;

// Extra commas
// Error: Trailing comma in object (valid in JS, but not in JSON)
const obj = {
  key1: 'value1',
  key2: 'value2',
}; // Valid in JS, invalid in JSON

// Error: Missing comma
const arr = [
  'item1'
  'item2'
  'item3'
]; // Missing commas between items

// Correct array
const correctArr = [
  'item1',
  'item2',
  'item3'
];

// Comma operator misuse
// Error: Using comma instead of semicolon
const x = 1, y = 2, z = 3; // x = 1, y and z are evaluated but not assigned

// Correct comma operator usage
const result = (a = 1, b = 2, a + b); // result = 3, a = 1, b = 2

// Function parameters with commas
function func(param1, param2, param3) {
  return param1 + param2 + param3;
}

// Object properties with commas
const obj = {
  prop1: 'value1',
  prop2: 'value2',
  prop3: 'value3'
};

String and Template Literal Errors

// Mismatched quotes
// Error: Unclosed string
const message = "Hello, World; // Missing closing quote

// Error: Mixed quotes
const mixed = 'Hello, World"; // Started with single quote, ended with double quote

// Error: Unescaped quote in string
const invalid = "He said "Hello" to me"; // Need to escape inner quotes

// Correct string escaping
const valid = "He said \"Hello\" to me";
const valid2 = 'He said \'Hello\' to me';

// Template literal errors
// Error: Unclosed template literal
const template = `Hello, ${name; // Missing backtick

// Error: Invalid expression in template literal
const invalid = `Hello, ${name + age}`; // Complex expressions need parentheses

// Correct template literal
const validTemplate = `Hello, ${name + age}`;
const validTemplate2 = `Hello, ${name} is ${age} years old`;

// Template literal with nested backticks
const nested = `Outer ${`inner ${name}`} outer`;

// Template literal with expressions
const calculate = `The result is ${a + b * c}`;
const conditional = `You are ${age >= 18 ? 'an adult' : 'a minor'}`;

Variable and Function Errors

// Using variables before declaration
// Error: ReferenceError
console.log(undefinedVariable); // Variable not declared

// Using const before assignment
// Error: SyntaxError
const x; // Declaration without initialization is fine
x = 5; // Assignment to const variable

// Redeclaration errors
// Error: SyntaxError in strict mode
let x = 1;
let x = 2; // Cannot redeclare let variable

// Function declaration errors
// Error: Duplicate parameter names
function duplicate(a, a, b) { // Parameter 'a' is duplicated
  return a + b;
}

// Error: Invalid function name
function 123invalid() { // Function name cannot start with number
  return 'test';
}

// Arrow function errors
// Error: Invalid arrow function syntax
const invalid = (a, b) => { return a + b; // Missing closing brace

// Error: Arrow function with invalid return
const invalid2 = (a, b) => return a + b; // Need braces for multi-line

// Correct arrow function
const valid = (a, b) => a + b;
const valid2 = (a, b) => {
  return a + b;
};

// Generator function errors
// Error: yield used outside generator
function invalidGenerator() {
  yield 1; // yield only valid in generator functions
}

// Correct generator function
function* validGenerator() {
  yield 1;
  yield 2;
}

Best Practices

Following best practices helps write clean, maintainable, and error-free JavaScript code.

Code Formatting

// Consistent indentation
// Use 2 or 4 spaces (be consistent)
if (condition) {
  // Indent with 2 spaces
  doSomething();
  if (anotherCondition) {
    // Indent nested blocks
    doSomethingElse();
  }
}
}

// Consistent spacing around operators
const result = a + b; // Spaces around operators
const comparison = x >= y; // Spaces around comparison operators
const assignment = z = 10; // Spaces around assignment

// Line length limits
// Keep lines under 80-120 characters for readability
const longLine = 'This is a very long line that should be broken up ' +
                  'for better readability';

// Consistent brace placement
// K&R style
if (condition) {
  doSomething();
}

// Allman style
if (condition)
{
  doSomething();
}

// Be consistent within project

// Consistent quote usage
// Use single quotes for strings
const message = 'Hello, World!';

// Use double quotes for HTML attributes
const html = "
Hello
"; // Be consistent within project // Consistent semicolon usage // Always use semicolons const a = 1; const b = 2; const c = a + b; // Or never use semicolons (rely on ASI) const a = 1 const b = 2 const c = a + b // Be consistent within project // Consistent naming conventions // camelCase for variables and functions const userName = 'john'; const getUserData = () => { /* ... */ }; // PascalCase for classes class UserService { constructor() { // ... } } // UPPER_SNAKE_CASE for constants const API_BASE_URL = 'https://api.example.com'; const MAX_RETRY_COUNT = 3; // Be consistent within project

Error Prevention

// Use strict mode
'use strict';
// Prevents common mistakes and enables better error reporting

// Use const and let instead of var
const constant = 'value'; // Cannot be reassigned
let variable = 'value'; // Block-scoped

// Initialize variables
let count = 0; // Initialize to avoid undefined
let items = []; // Initialize arrays

// Check for undefined before use
function processValue(value) {
  if (value !== undefined) {
    return value * 2;
  }
  return 0;
}

// Use parameter defaults
function greet(name = 'Guest') {
  return `Hello, ${name}!`;
}

// Use default values for destructuring
const { name = 'Anonymous', age = 0 } = person;

// Validate function parameters
function divide(a, b) {
  if (typeof a !== 'number' || typeof b !== 'number') {
    throw new TypeError('Both parameters must be numbers');
  }
  
  if (b === 0) {
    throw new Error('Cannot divide by zero');
  }
  
  return a / b;
}

// Use try-catch for error-prone operations
try {
  const result = riskyOperation();
  console.log('Success:', result);
} catch (error) {
  console.error('Error:', error.message);
  // Handle error appropriately
}

// Use modern syntax when available
// Use arrow functions for simple callbacks
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);

// Use template literals for string concatenation
const name = 'John';
const greeting = `Hello, ${name}!`;

// Use destructuring for cleaner code
const { name, age } = person;
const [first, second] = [1, 2, 3];

// Use optional chaining for safe property access
const user = {
  name: 'John',
  profile: {
    email: 'john@example.com'
  }
};

const email = user?.profile?.email ?? 'No email';

// Use nullish coalescing for default values
const timeout = settings?.timeout ?? 5000;
const displayName = user?.name ?? 'Anonymous';

Code Organization

// Use meaningful variable names
const userAge = 30; // Good
const x = 30; // Bad

const calculateTotal = (price, tax) => price * (1 + tax); // Good
const calc = (p, t) => p * (1 + t); // Bad

// Group related code
// User management functions
class UserService {
  async getUser(id) {
    // Get user logic
  }
  
  async createUser(userData) {
    // Create user logic
  }
  
  async updateUser(id, updates) {
    // Update user logic
  }
  
  async deleteUser(id) {
    // Delete user logic
  }
}

// Use comments to explain complex logic
function complexCalculation(data) {
  // Step 1: Normalize input data
  const normalized = normalizeData(data);
  
  // Step 2: Calculate base value
  const base = calculateBase(normalized);
  
  // Step 3: Apply modifiers
  const modified = applyModifiers(base, normalized.modifiers);
  
  return modified;
}

// Break down complex functions
function processLargeDataset(dataset) {
  const cleaned = cleanData(dataset);
  const validated = validateData(cleaned);
  const processed = processData(validated);
  const formatted = formatData(processed);
  
  return formatted;
}

// Use early returns
function validateUser(user) {
  if (!user) {
    return { valid: false, error: 'No user provided' };
  }
  
  if (!user.email) {
    return { valid: false, error: 'Email is required' };
  }
  
  if (!user.email.includes('@')) {
    return { valid: false, error: 'Invalid email format' };
  }
  
  return { valid: true };
}

// Use consistent error handling
function robustOperation(input) {
  try {
    const result = processInput(input);
    return { success: true, result };
  } catch (error) {
    console.error('Operation failed:', error.message);
    return { success: false, error: error.message };
  }
}

Summary

Key Takeaways

  • JavaScript syntax defines rules for writing valid code
  • Statements perform actions, expressions evaluate to values
  • Control structures direct program flow (if, for, while, switch)
  • Functions and classes have specific syntax rules
  • Modern JavaScript introduces template literals, destructuring, and spread syntax
  • Operators combine values following precedence and associativity rules
  • Common syntax errors include bracket mismatches and quote issues

Best Practices

  • Use consistent indentation and spacing
  • Follow naming conventions (camelCase, PascalCase, UPPER_SNAKE_CASE)
  • Use const and let instead of var for better scoping
  • Initialize variables and check for undefined values
  • Use modern syntax (template literals, destructuring, arrow functions)
  • Use strict mode to catch common errors early
  • Write meaningful comments for complex logic
  • Use early returns to reduce nesting
  • Group related code and use consistent error handling

Common Pitfalls

  • Mismatched brackets, parentheses, or quotes
  • Forgetting semicolons or using them inconsistently
  • Using variables before declaration
  • Redeclaring variables with let/const
  • Using reserved words as identifiers
  • Invalid function names or parameter names
  • Not handling undefined values properly
  • Complex expressions without proper parentheses
  • Inconsistent code formatting and naming