Docs

README

1.2 Basic Syntax

šŸ“š Table of Contents

  1. •Statements vs Expressions
  2. •Identifiers
  3. •Whitespace Rules
  4. •Semicolons and ASI
  5. •Comments

Statements vs Expressions

Understanding the difference between statements and expressions is fundamental to understanding how JavaScript code works.

Expressions

An expression is any valid unit of code that produces a value.

// All of these are expressions - they produce values
5; // → 5
5 + 3; // → 8
('Hello'); // → "Hello"
'Hello' + ' World'; // → "Hello World"
x; // → value of x
x > 5; // → true or false
x ? 'yes' : 'no'; // → "yes" or "no"
myFunction()[(1, 2, 3)]; // → return value of function // → array
{
  name: 'John';
} // → object

Types of Expressions:

TypeExampleResult
Arithmetic5 + 3 * 211
String"Hello" + " World""Hello World"
Logicaltrue && falsefalse
Primarythis, myVariableThe value
Left-hand-sideobj.propertyProperty value
Assignmentx = 55
Unary!true, typeof xDepends on operator
Ternaryx > 5 ? "big" : "small"One of the values

Key Insight: Expressions Can Be Used Anywhere a Value Is Expected

// Expressions can be:

// 1. Assigned to variables
let result = 5 + 3;

// 2. Passed as function arguments
console.log(5 + 3);

// 3. Used in other expressions
let total = (5 + 3) * 2;

// 4. Returned from functions
function add() {
  return 5 + 3;
}

Statements

A statement is an instruction that performs an action. Statements do NOT produce values that can be used elsewhere.

// These are statements - they perform actions

// Variable declaration statement
let x = 5;

// If statement
if (x > 3) {
  console.log('Big');
}

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

// Function declaration statement
function sayHello() {
  console.log('Hello');
}

// Switch statement
switch (x) {
  case 1:
    break;
  default:
    break;
}

Types of Statements:

Statement TypeExample
Declarationlet x = 5;
Assignmentx = 10; (also an expression!)
Conditionalif (condition) {...}
Loopfor, while, do...while
Jumpbreak, continue, return
Try-Catchtry {...} catch {...}
Import/Exportimport x from 'module'

The Critical Difference

// āŒ This WON'T work - if statement doesn't produce a value
let result = if (true) { 5 };  // SyntaxError!

// āœ… This WORKS - ternary expression produces a value
let result = true ? 5 : 0;     // result = 5

// āŒ This WON'T work - can't use a statement where expression is expected
console.log(if (true) { 5 });  // SyntaxError!

// āœ… This WORKS - expressions can be used as arguments
console.log(true ? 5 : 0);     // 5

Expression Statements

Some expressions can stand alone as statements:

// These are expression statements (expressions used as statements)
5 + 3; // Valid but useless
x = 5; // Assignment expression as statement
myFunction(); // Function call expression as statement
x++; // Increment expression as statement

Visual Summary:

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    EXPRESSIONS                       │
│   • Produce values                                   │
│   • Can be used anywhere values are expected         │
│   • Examples: 5 + 3, "hello", x > 5, fn()           │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    STATEMENTS                        │
│   • Perform actions                                  │
│   • Cannot be used where values are expected         │
│   • Examples: if, for, while, function declaration  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Identifiers

Identifiers are names given to variables, functions, classes, and other entities in your code.

Rules for Identifiers:

RuleValid ExamplesInvalid Examples
Must start with letter, _, or $name, _private, $element123abc, #tag
Can contain letters, digits, _, $user2, first_nameuser-name, my.var
Case-sensitiveName ≠ name ≠ NAME—
Cannot be reserved words—if, for, class

Valid Identifiers:

// All of these are valid
let name;
let Name;
let NAME;
let _private;
let $jquery;
let camelCase;
let snake_case;
let PascalCase;
let user123;
let _123;
let $_$;

Invalid Identifiers:

// These will cause errors
let 123user;     // Cannot start with number
let my-variable; // Cannot contain hyphen
let my.variable; // Cannot contain dot
let my variable; // Cannot contain space
let class;       // Reserved word
let if;          // Reserved word
let for;         // Reserved word

Reserved Words (Cannot Be Used as Identifiers):

// Keywords
break       case        catch       class       const
continue    debugger    default     delete      do
else        export      extends     finally     for
function    if          import      in          instanceof
let         new         return      static      super
switch      this        throw       try         typeof
var         void        while       with        yield

// Future reserved words (strict mode)
implements  interface   package     private     protected
public

// Literals
null        true        false

// Special (avoid using)
undefined   NaN         Infinity    arguments   eval

Naming Conventions (Best Practices):

// Variables and functions: camelCase
let userName = 'John';
let firstName = 'Jane';
function calculateTotal() {}
function getUserById() {}

// Constants: UPPER_SNAKE_CASE
const MAX_SIZE = 100;
const API_BASE_URL = 'https://api.example.com';
const DEFAULT_TIMEOUT = 3000;

// Classes: PascalCase
class UserAccount {}
class ShoppingCart {}
class HttpRequest {}

// Private members (convention): _prefix or #prefix
let _privateVar = 'internal';
class MyClass {
  #privateField = 'truly private';
}

// Boolean variables: is/has/can prefixes
let isActive = true;
let hasPermission = false;
let canEdit = true;

// Functions: verb prefixes
function getUser() {}
function setName() {}
function validateInput() {}
function calculatePrice() {}
function handleClick() {}

Meaningful Names:

// āŒ Bad - Unclear meaning
let x = 5;
let temp = 'John';
let data = [1, 2, 3];
function fn() {}

// āœ… Good - Clear and descriptive
let userAge = 5;
let userName = 'John';
let productPrices = [1, 2, 3];
function calculateDiscount() {}

Whitespace Rules

JavaScript is generally whitespace-insensitive, but there are important rules to understand.

Where Whitespace Doesn't Matter:

// These are all equivalent:
let x = 5 + 3;
let x = 5 + 3;
let x = 5 + 3;

// These are equivalent:
function greet(name) {
  return 'Hello ' + name;
}

function greet(name) {
  return 'Hello ' + name;
}

function greet(name) {
  return 'Hello ' + name;
}

Where Whitespace Matters:

1. Inside Strings

// Whitespace is preserved inside strings
let message1 = 'Hello World'; // Has one space
let message2 = 'Hello  World'; // Has two spaces
let message3 = 'Hello   World'; // Has three spaces

// These are NOT equal
'Hello World' === 'Hello  World'; // false

2. Between Keywords and Identifiers

// āœ… Correct - space required
let x = 5;
typeof x;
return value;
new Object();

// āŒ Wrong - no space causes errors or different meaning
letx = 5; // Error: letx is not defined
typeofx; // Error: typeofx is not defined
returnvalue; // Error: returnvalue is not defined

3. Line Breaks Can Affect Behavior (ASI)

// Watch out for automatic semicolon insertion!

// āŒ This returns undefined, not the object!
function getObject() {
  return;
  {
    name: 'John';
  }
}

// āœ… This returns the object correctly
function getObject() {
  return {
    name: 'John',
  };
}

Types of Whitespace Characters:

CharacterNameEscape Sequence
SpaceSpace
TabHorizontal Tab\t
NewlineLine Feed\n
Carriage ReturnCarriage Return\r

Indentation Best Practices:

// Use consistent indentation (2 or 4 spaces)

// 2-space indentation
function example() {
  if (true) {
    console.log('Hello');
  }
}

// 4-space indentation
function example() {
  if (true) {
    console.log('Hello');
  }
}

// Avoid mixing tabs and spaces!

Semicolons and ASI

Semicolons in JavaScript

Semicolons (;) are used to terminate statements in JavaScript.

// Statements with semicolons
let x = 5;
let y = 10;
console.log(x + y);

Automatic Semicolon Insertion (ASI)

JavaScript has a feature called Automatic Semicolon Insertion (ASI) that automatically inserts semicolons in certain situations.

// JavaScript automatically inserts semicolons here:
let x = 5; // ; inserted
let y = 10; // ; inserted
console.log(x + y); // ; inserted

When ASI Inserts Semicolons:

  1. •Before a line break (if the next token would cause an error)
  2. •Before a closing brace }
  3. •At the end of the program

ASI Rules in Detail:

// Rule 1: Before line break when next line would cause error
let a = 1;
let b = 2;
// Becomes: let a = 1; let b = 2;

// Rule 2: Before closing brace
if (true) {
  return 5;
}
// Becomes: if (true) { return 5; }

// Rule 3: After return, break, continue, throw + line break
return;
5;
// Becomes: return; 5; (NOT return 5!)

Dangerous ASI Cases:

Case 1: Return Statement

// āŒ DANGER! Returns undefined, not the object
function getUser() {
  return;
  {
    name: 'John';
  }
}
// ASI makes it: return; { name: "John" };

// āœ… CORRECT - Start object on same line
function getUser() {
  return {
    name: 'John',
  };
}

Case 2: Lines Starting with (, [, /

// āŒ DANGER! These can cause problems without semicolons
let x = 5(function () {
  console.log('IIFE');
})();
// Interpreted as: let x = 5(function() {...})() - Error!

let y = (10)[(1, 2, 3)].forEach((n) => console.log(n));
// Interpreted as: let y = 10[1, 2, 3].forEach(...) - Error!

// āœ… SAFE - Add semicolons
let x = 5;
(function () {
  console.log('IIFE');
})();

let y = 10;
[1, 2, 3].forEach((n) => console.log(n));

Case 3: No ASI After These Tokens

ASI does NOT insert semicolons after:

  • •++ and --
  • •for, while, if, switch, try
  • •Empty statements
// These work across lines:
x;
++y;
// Becomes: x++; y; (NOT x; ++y;)

The Great Semicolon Debate

There are two camps in JavaScript:

Team Semicolons (Always Use Them)

// Explicit semicolons - safer and clearer
let name = 'John';
let age = 30;

function greet() {
  return 'Hello';
}

Team No Semicolons (Rely on ASI)

// No semicolons - cleaner looking
let name = 'John';
let age = 30;

function greet() {
  return 'Hello';
}

Recommendation for Beginners:

Always use semicolons. Here's why:

  1. •Makes code intentions explicit
  2. •Avoids subtle bugs from ASI
  3. •More consistent with other languages
  4. •Easier to debug and read
  5. •Most style guides recommend them

When Semicolons Are NOT Used:

// After function declarations
function greet() {
  console.log('Hello');
} // No semicolon needed here

// After if/else blocks
if (true) {
  console.log('Yes');
} // No semicolon needed here

// After for/while loops
for (let i = 0; i < 5; i++) {
  console.log(i);
} // No semicolon needed here

// After class declarations
class Person {
  constructor() {}
} // No semicolon needed here

// BUT semicolons ARE used after:
// - Variable declarations: let x = 5;
// - Expression statements: console.log("Hi");
// - Function expressions: let greet = function() {};
// - Class expressions: let Person = class {};

Comments

Comments are used to explain code and make it more readable. JavaScript ignores comments during execution.

Single-Line Comments

Use // for single-line comments:

// This is a single-line comment
let x = 5; // This comment is at the end of a line

// You can have multiple
// single-line comments
// for longer explanations

Multi-Line Comments

Use /* */ for multi-line comments:

/* This is a 
   multi-line comment
   spanning multiple lines */

/*
 * This is a common style
 * for multi-line comments
 * with asterisks for alignment
 */

/* Single line using multi-line syntax */

Documentation Comments (JSDoc)

JSDoc comments use /** */ and are used for documentation:

/**
 * Calculates the sum of two numbers.
 *
 * @param {number} a - The first number
 * @param {number} b - The second number
 * @returns {number} The sum of a and b
 * @example
 * // Returns 8
 * add(5, 3);
 */
function add(a, b) {
  return a + b;
}

/**
 * Represents a person.
 * @class
 */
class Person {
  /**
   * Create a person.
   * @param {string} name - The person's name.
   * @param {number} age - The person's age.
   */
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

Common JSDoc Tags:

TagPurposeExample
@paramDocument a parameter@param {string} name - User's name
@returnsDocument return value@returns {number} The result
@typeSpecify a type@type {string}
@exampleProvide usage example@example add(1, 2)
@deprecatedMark as deprecated@deprecated Use newMethod instead
@throwsDocument exceptions@throws {Error} If invalid input
@seeReference related items@see OtherClass
@todoMark incomplete work@todo Add validation

When to Comment:

āœ… Good Comments - Explain WHY

// Using bitwise OR for fast floor operation
// This is faster than Math.floor() in performance-critical code
let floored = 5.7 | 0;

// Workaround for Safari flexbox bug (issue #234)
container.style.minHeight = '1px';

// Rate limit to prevent API abuse
// Max 100 requests per minute
if (requestCount > 100) {
  throw new Error('Rate limit exceeded');
}

āŒ Bad Comments - Explain WHAT (Code Already Says This)

// Bad - explains the obvious
let x = 5; // Set x to 5
i++; // Increment i
arr.push(item); // Add item to array

// Good - no comment needed, code is self-explanatory
let userAge = 5;
currentIndex++;
shoppingCart.push(newItem);

Comment Best Practices:

// 1. Keep comments up to date with code changes
// āŒ Outdated comment
// Returns the user's full name
function getUser() {
  return { firstName: 'John', lastName: 'Doe' }; // Actually returns object!
}

// 2. Use comments to explain complex logic
// Calculate compound interest: A = P(1 + r/n)^(nt)
// Where: P = principal, r = rate, n = compounds per year, t = years
function compoundInterest(principal, rate, compounds, years) {
  return principal * Math.pow(1 + rate / compounds, compounds * years);
}

// 3. Mark temporary code or TODOs
// TODO: Refactor this to use async/await
// FIXME: This doesn't handle edge case when list is empty
// HACK: Temporary solution until API is fixed
// NOTE: This requires minimum browser version Chrome 80+

// 4. Use comments to section your code
// ==========================================
//              USER MANAGEMENT
// ==========================================

function createUser() {
  /* ... */
}
function deleteUser() {
  /* ... */
}

// ==========================================
//              DATA PROCESSING
// ==========================================

function processData() {
  /* ... */
}

Commenting Out Code:

// You can use comments to temporarily disable code:

function calculate() {
  let result = 0;

  // Old implementation - keeping for reference
  // result = complexCalculation();

  // New faster implementation
  result = optimizedCalculation();

  return result;
}

/*
 * Large block of code can be disabled like this
 * function oldFunction() {
 *     // ...
 * }
 */

VS Code Comment Shortcuts:

ShortcutAction
Ctrl + /Toggle line comment
Shift + Alt + AToggle block comment
Ctrl + K, Ctrl + CAdd line comment
Ctrl + K, Ctrl + URemove line comment

šŸŽÆ Key Takeaways

  1. •Expressions produce values, statements perform actions
  2. •Identifiers follow specific naming rules and conventions (camelCase for variables)
  3. •Whitespace generally doesn't matter except in strings and certain contexts
  4. •Semicolons can be automatic (ASI) but explicit semicolons are recommended
  5. •Comments should explain WHY, not WHAT - use JSDoc for documentation

āž”ļø Next Module

Continue to Module 2: Variables & Data Types to learn about storing and working with data in JavaScript!

README - JavaScript Tutorial | DeepML