Introduction

JavaScript is a versatile, prototype-based language that runs in browsers and on servers through Node.js. On the web, scripts are loaded via the <script> tag. Modern sites prefer non-blocking delivery using defer or type="module".

Use DevTools to inspect and iterate quickly. Start with console.log() for visibility and lean on the Sources/Debugger panels to set breakpoints and step through code.

<script src="app.js" defer></script>
<script type="module">
  import { init } from './app.js';
  init();
</script>
Basic Syntax

Prefer const for bindings that do not get reassigned and let for reassignable ones. Avoid var in modern code. Blocks using {} create scope, which helps avoid leaking identifiers.

Automatic Semicolon Insertion exists, but being explicit improves consistency. Single-line comments start with //; multi-line use /* ... */.

const answer = 42;
let count = 0;
count = count + 1;
Data Types

JavaScript has primitive and reference types. Use typeof and Array.isArray() to inspect values. Objects and arrays are passed by reference.

typeof 42 === "number"
typeof "hi" === "string"
typeof null === "object"
Array.isArray([1,2,3]) === true
Control Flow

Use if/else for branching, for/while for loops, and prefer array methods like map, filter, and reduce for declarative iteration.

const nums = [1,2,3,4];
const evens = nums.filter(n => n % 2 === 0);
const doubled = evens.map(n => n * 2);
Functions

Functions can be declared or expressed. Declarations are hoisted; expressions are not. Arrow functions have lexical this and concise syntax.

function greet(name) {
  return `Hi ${name}`;
}

const double = n => n * 2;
DOM and Events

The DOM reflects your document as a tree. Query with document.querySelector and update via properties or attributes. Use addEventListener for interactivity and prefer event delegation for dynamic content.

const btn = document.querySelector('#btn');
const out = document.querySelector('#out');
btn.addEventListener('click', () => {
  out.textContent = 'Button clicked!';
});
Waiting…
Promises & Async/Await

Promises model asynchronous results. async/await provides sequential syntax on top of promises. Handle errors with try/catch and consider Promise.all for parallel work.

async function loadUser(id) {
  try {
    const res = await fetch(`https://api.example.com/users/${id}`);
    if (!res.ok) throw new Error('Network error');
    const data = await res.json();
    return data;
  } catch (err) {
    console.error(err);
    return null;
  }
}
Modules & Tooling

Use ES modules with type="module" and the import/export syntax. For production, bundlers and dev servers provide transforms, hot reload, and optimizations.

// utils.js
export function sum(a, b) { return a + b; }

// app.js
import { sum } from './utils.js';
console.log(sum(2,3));
Best Practices