Published on

Notes on Advanced JavaScript

Authors

Frames and Windows

  • Popups and Window Methods:
    • window.open(url, [name], [specs], [replace]): Opens a new browser window or tab.
      • url: URL to load.
      • name: Target name (e.g., _blank, _self, or custom name for specific window).
      • specs: Comma-separated list of features (width, height, toolbar, menubar, etc.).
    • window.close(): Closes the current window/tab. Only works for windows opened by window.open().
    • window.postMessage(message, targetOrigin): Sends a message to another window (see Cross-window communication).
    • window.opener: Reference to the window that opened the current window.
    • popup.focus(): Brings the popup window to the foreground.
  • Cross-Window Communication:
    • Same-Origin Policy: A security measure. Scripts from one origin (protocol + host + port) cannot access content from another origin.
    • window.postMessage(): The standard and safest way to communicate between windows/frames from different origins.
      • Sends message to a target window (e.g., window.opener, iframe.contentWindow).
      • targetOrigin: String specifying origin (e.g., 'https://example.com') or '*' (any origin). Crucial for security; always specify the exact origin if known.
      • Event listener on receiving side: window.addEventListener('message', handler). handler.data contains the message, handler.origin contains sender's origin.
    • Same-Origin Access: If windows/frames are from the same origin:
      • Direct access: iframe.contentWindow.document, popup.document.
      • Direct function calls: iframe.contentWindow.someFunction().
      • Parent/Child access: window.parent, iframe.contentWindow, window.frames[index/name].
  • The Clickjacking Attack:
    • A malicious technique where a user is tricked into clicking on something different from what they perceive, typically by overlaying an invisible or opaque layer over a legitimate webpage.
    • Often involves an <iframe> set with opacity: 0 or positioned off-screen, with a malicious page behind it.
    • Defense:
      • X-Frame-Options HTTP header: DENY, SAMEORIGIN, ALLOW-FROM uri. Prevents embedding your page in <iframe>s.
      • Content Security Policy (CSP) frame-ancestors directive: More flexible and powerful than X-Frame-Options.

Binary Data, Files

  • ArrayBuffer, Binary Arrays:
    • ArrayBuffer: A raw binary data buffer. Stores a fixed number of bytes, but no direct methods to manipulate contents. new ArrayBuffer(length).
    • TypedArray (Views): Provides methods to read/write ArrayBuffer contents as specific data types (e.g., Uint8Array, Int32Array, Float64Array).
      • new Uint8Array(buffer, [byteOffset], [length]): View of 8-bit unsigned integers.
      • Views don't store data themselves; they are "windows" into an ArrayBuffer.
    • DataView: A more flexible view for mixed data types and byte order, allowing arbitrary offset access.
      • new DataView(buffer, [byteOffset], [byteLength]).
      • Methods: dataView.getUint8(offset), dataView.getFloat64(offset, littleEndian).
    • Use Cases: Manipulating raw image data, audio processing, WebSockets (binary frames), WebAssembly.
  • TextDecoder and TextEncoder:
    • TextEncoder: Converts strings (UTF-8) into Uint8Array.
      • new TextEncoder().encode(string): Returns Uint8Array of UTF-8 bytes.
    • TextDecoder: Converts Uint8Array bytes into strings (UTF-8 by default, supports other encodings).
      • new TextDecoder([encoding], [options]).
      • decoder.decode(uint8Array): Returns string.
    • Use Cases: Working with network protocols, file manipulation, where data is typically byte-encoded.
  • Blob:
    • Blob (Binary Large Object): Represents immutable raw data. Can contain any type of data, not necessarily JavaScript-native binary formats.
    • new Blob(array, [options]): Creates a Blob. array can contain ArrayBuffer, TypedArray, Blob, strings. options.type sets MIME type.
    • Use Cases:
      • Downloading generated content (e.g., <a> tag href with URL.createObjectURL(blob)).
      • Uploading data via fetch or XMLHttpRequest (FormData).
      • Slicing large files: blob.slice(start, end, [contentType]).
      • Blob objects can be easily converted to text using FileReader.
  • File and FileReader:
    • File: A specific type of Blob with additional properties like name and lastModifiedDate. File objects are typically obtained from user input (e.g., <input type="file"> files property) or drag-and-drop.
    • FileReader: An API to asynchronously read the contents of File or Blob objects into memory.
      • new FileReader(): Creates a reader.
      • Methods:
        • reader.readAsText(blob, [encoding]): Reads as text.
        • reader.readAsArrayBuffer(blob): Reads as ArrayBuffer.
        • reader.readAsDataURL(blob): Reads as base64 encoded string (data URL).
      • Events: reader.onload (on successful read), reader.onerror (on error), reader.onprogress.
      • reader.result: Contains the result of the read operation.
    • Use Cases: Displaying image previews, client-side file parsing, client-side encryption/compression.

Network Requests

  • Fetch API:
    • A modern, promise-based API for making network requests. Replaces XMLHttpRequest for most use cases.
    • fetch(url, [options]): Returns a Promise that resolves to a Response object.
    • Response object: Represents the response from the server.
      • Properties: response.ok, response.status, response.headers.
      • Methods (to parse body): response.json(), response.text(), response.blob(), response.arrayBuffer(), response.formData(). All return Promises.
    • Request Options:
      • method: HTTP method ('GET', 'POST', etc.).
      • headers: HTTP headers (e.g., {'Content-Type': 'application/json'}).
      • body: Request body (e.g., JSON.stringify(data), FormData, Blob, URLSearchParams).
      • mode: Request mode ('cors', 'no-cors', 'same-origin').
      • credentials: Cookie/HTTP authentication handling ('omit', 'same-origin', 'include').
      • cache: Cache mode ('default', 'no-store', etc.).
      • signal: AbortSignal for aborting requests.
  • FormData:
    • An object that allows you to construct a set of key/value pairs representing form fields, primarily for sending data with fetch or XMLHttpRequest via multipart/form-data encoding.
    • new FormData([formElement]): Creates FormData from an existing <form> or an empty one.
    • formData.append(name, value, [filename]): Adds a new field. value can be a string, Blob, or File.
    • formData.get(name), formData.getAll(name), formData.has(name), formData.delete(name).
    • Automatically sets Content-Type: multipart/form-data header when sent via fetch.
  • Fetch: Download Progress:
    • Requires working with response.body as a ReadableStream.
    • Read chunks using response.body.getReader().
    • Track loadedBytes against response.headers.get('Content-Length').
    • More complex than simple XMLHttpRequest progress events.
  • Fetch: Abort:
    • Uses AbortController and AbortSignal.
    • const controller = new AbortController();
    • const signal = controller.signal;
    • fetch(url, { signal });
    • controller.abort(); (to cancel the request).
    • The fetch Promise will reject with an AbortError.
  • Fetch: Cross-Origin Requests:
    • By default, fetch operates under the Same-Origin Policy.
    • mode: 'cors' (default for requests to other origins): Allows cross-origin requests, subject to CORS headers from the server.
    • credentials: 'include': Sends cookies and HTTP authentication with cross-origin requests (requires Access-Control-Allow-Credentials: true from server).
  • URL Objects:
    • new URL(url, [base]): Creates a URL object for parsing and manipulating URLs.
    • Properties: href, protocol, host, hostname, port, pathname, search, hash, username, password.
    • URLSearchParams via url.searchParams: Methods to manage query parameters (e.g., append, delete, get, set).
    • Use Cases: Building complex URLs, parsing incoming URLs, safely encoding query parameters.
  • XMLHttpRequest (XHR):
    • The older API for making HTTP requests. Event-based.
    • new XMLHttpRequest()
    • xhr.open(method, url, [async], [user], [password])
    • xhr.send([body])
    • Events: xhr.onload, xhr.onerror, xhr.onprogress (for upload/download progress), xhr.onreadystatechange.
    • xhr.responseType: 'json', 'text', 'blob', 'arraybuffer', 'document'.
    • xhr.status, xhr.statusText, xhr.response.
    • Still relevant for: file upload progress (simpler than Fetch), older codebases, specific browser features not yet in Fetch.
  • Resumable File Upload:
    • Breaking large files into smaller chunks (Blob.slice()).
    • Uploading chunks sequentially or in parallel.
    • Maintaining upload state (which chunks sent) on client and server.
    • If upload is interrupted, can resume from the last successfully sent chunk.
    • Commonly implemented with XHR progress events or Fetch with custom stream readers.
  • Long Polling:
    • Client sends a request to the server, and the server holds the connection open until new data is available or a timeout occurs.
    • Once data is sent (or timeout), the connection closes, and the client immediately opens a new request.
    • Drawbacks: High overhead (many connections), potential for delays if server is slow.
    • Alternative: WebSockets, Server-Sent Events.
  • WebSocket:
    • Provides a full-duplex (two-way) communication channel over a single, long-lived TCP connection.
    • new WebSocket(url, [protocols]): Connects to a WebSocket server (ws:// or wss:// protocol).
    • Events: ws.onopen, ws.onmessage, ws.onclose, ws.onerror.
    • Methods: ws.send(data), ws.close([code], [reason]).
    • Benefits: Low overhead, real-time communication, ideal for chat, gaming, live updates.
  • Server Sent Events (SSE):
    • A unidirectional (server-to-client only) event streaming protocol built on top of HTTP.
    • new EventSource(url): Connects to an SSE endpoint.
    • Server sends events in a specific text/event-stream format.
    • Events: source.onopen, source.onmessage, source.onerror. Can also listen for custom event names sent by server: source.addEventListener('customEvent', handler).
    • Automatically reconnects on connection loss.
    • Benefits: Simpler than WebSockets for server-push only scenarios (e.g., stock tickers, news feeds), leverages HTTP.

Storing Data in the Browser

  • Cookies, document.cookie:
    • Small strings of data stored by the browser, sent with every HTTP request to the same domain.
    • document.cookie: A getter/setter that returns/sets the entire cookie string.
    • Properties: name=value, expires, max-age, path, domain, secure, HttpOnly, SameSite.
    • Limitations: Small size (approx. 4KB per domain), sent with every request (performance overhead), primarily for server-side state management (sessions, authentication).
  • LocalStorage, SessionStorage:
    • Web Storage API: Key-value pairs storage in the browser.
    • localStorage: Stores data with no expiration time. Data persists even after browser restart.
    • sessionStorage: Stores data only for the duration of the browser session (until the tab/window is closed).
    • Methods:
      • storage.setItem(key, value): Stores value (string).
      • storage.getItem(key): Retrieves value (string).
      • storage.removeItem(key): Removes key.
      • storage.clear(): Clears all items.
      • storage.length: Number of items.
    • Limitations: Stores only strings (must JSON.stringify/parse objects), synchronous (can block main thread for large data), domain-specific (Same-Origin Policy applies), size limit (typically 5-10MB).
    • Use Cases: Client-side caching, user preferences, offline data.
  • IndexedDB:
    • A low-level API for client-side storage of significant amounts of structured data, including files/blobs.
    • Key Concepts:
      • Database: IDBDatabase (multiple per origin).
      • Object Store: Like tables, store records.
      • Key: Unique identifier for each record.
      • Index: For fast lookups on non-key properties.
      • Transaction: All operations must be inside a transaction (IDBTransaction). Atomic.
      • Request: Most operations return IDBRequest objects, which fire success or error events.
    • Asynchronous: All operations are non-blocking, using events or Promises (with wrapper libraries).
    • Use Cases: Offline web applications, large client-side data storage, caching complex data structures.
    • Complexity: More complex API than Web Storage, often used with helper libraries (e.g., localforage).

Animation

  • Bezier Curve:
    • A mathematical curve used to define smooth paths and easing functions in animations.
    • Defined by control points: P0 (start), P1, P2, ... Pn (end).
    • Cubic Bezier (cubic-bezier(x1, y1, x2, y2)): Common in CSS transition-timing-function and animation-timing-function, defining the speed curve of an animation.
      • linear, ease, ease-in, ease-out, ease-in-out are pre-defined Bezier curves.
  • CSS-Animations:
    • Declarative animation using CSS properties.
    • transition: Animates changes in CSS properties over a specified duration.
      • transition-property, transition-duration, transition-timing-function (Bezier), transition-delay.
    • animation: More powerful, allows complex multi-step animations (keyframes).
      • @keyframes: Defines animation steps.
      • animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode.
    • Benefits: Hardware-accelerated (often smooth), simpler for many UI effects, separates concerns (style in CSS).
    • Limitations: Less control over complex logic, interaction, or precise timing than JavaScript.
  • JavaScript Animations:
    • Programmatic animation using requestAnimationFrame.
    • requestAnimationFrame(callback): Schedules a function to run before the browser's next repaint. Optimized for smooth animations.
    • Process:
      1. Define animation state (e.g., current position, progress).
      2. requestAnimationFrame loop: In each frame, update state based on elapsed time, apply changes to DOM (e.g., elem.style.left = ...), and schedule next frame.
      3. Stop loop when animation finishes.
    • Benefits: Fine-grained control, can animate any property, easily integrate with user interaction, complex physics or interpolated values.
    • Limitations: More code, can be less performant if not optimized (e.g., forcing reflows), requires careful requestAnimationFrame management.
    • Web Animations API (WAAPI): A newer API aiming to bridge CSS and JS animations, providing a JS interface for animating DOM elements efficiently. elem.animate().

Web Components

  • From the Orbital Height: A set of standards allowing developers to create reusable custom HTML elements with encapsulated functionality and styling.
  • Custom Elements:
    • CustomElementRegistry.define(tagName, constructor, [options]): Registers a new custom element.
      • tagName: Must contain a hyphen (e.g., 'my-element').
      • constructor: ES6 class extending HTMLElement.
    • Lifecycle Callbacks: Special methods called at different stages of an element's life:
      • connectedCallback: When element is added to DOM.
      • disconnectedCallback: When element is removed from DOM.
      • adoptedCallback: When element is moved to a new document.
      • attributeChangedCallback(name, oldValue, newValue): When an observed attribute changes.
    • static observedAttributes: Array of attribute names to observe.
  • Shadow DOM:
    • A way to encapsulate a component's internal DOM structure and styling.
    • elem.attachShadow({ mode: 'open' | 'closed' }): Attaches a shadow root to an element.
    • Content inside the shadow root is separate from the main document's DOM.
    • Encapsulation:
      • CSS inside Shadow DOM only applies to its own content.
      • CSS from main document generally does not penetrate Shadow DOM (except inherited properties).
      • IDs and classes inside Shadow DOM do not conflict with IDs/classes in the main document.
    • Use Cases: Reusable UI widgets, ensuring consistent styling, preventing style conflicts.
  • Template Element:
    • <template>: Holds HTML content that is not rendered when the page loads. It's a dormant DOM fragment.
    • template.content: Returns a DocumentFragment containing the template's content.
    • Use Cases: Defining reusable blocks of HTML that can be cloned and inserted into the DOM (especially with Custom Elements and Shadow DOM).
  • Shadow DOM Slots, Composition:
    • <slot>: A placeholder element inside Shadow DOM. It defines where children from the light DOM (main document) will be rendered.
    • named slots: <slot name="foo"> allows specific light DOM children (e.g., <span slot="foo">) to be projected into specific slots.
    • Composition: The process of rendering content from the light DOM into the Shadow DOM via slots. This allows the component's internal structure to combine with user-provided content.
  • Shadow DOM Styling:
    • Default: Styles defined within the Shadow DOM are scoped to it.
    • Inherited properties: Some CSS properties (e.g., font-size, color) inherit from the main document into the Shadow DOM.
    • ::part() pseudo-element: Allows main document CSS to style specific, exposed parts of a Shadow DOM component (<div part="button">). Component author must explicitly declare parts.
    • CSS Custom Properties (Variables): Can be used to customize Shadow DOM styles from the outside (--my-color: red;).
    • ::slotted() pseudo-element: Styles content within a slot.
  • Shadow DOM and Events:
    • Events originating from inside Shadow DOM typically re-target to the host element when bubbling up to the light DOM.
    • event.target: Will be the host element (or a slot if a slot is the actual target).
    • event.composedPath(): Returns an array of DOM nodes through which the event propagated, showing the true path across Shadow DOM boundaries.
    • event.composed: true if the event can bubble out of the Shadow DOM.

Regular Expressions

  • Patterns and Flags:
    • RegExp Literals: /pattern/flags (e.g., /abc/i).
    • RegExp Constructor: new RegExp('pattern', 'flags') (e.g., new RegExp('abc', 'i')). Useful for dynamic patterns.
    • Flags:
      • i (case-insensitive): Ignores case.
      • g (global): Finds all matches, not just the first.
      • m (multiline): ^ and $ match start/end of lines, not just start/end of string.
      • u (unicode): Enables full Unicode support (e.g., for surrogate pairs, \p{...}).
      • s (dotAll): . matches all characters, including newlines (\n).
      • y (sticky): Matches only from the current position (specified by lastIndex).
  • Character Classes:
    • \d: Digit (0-9).
    • \D: Non-digit.
    • \s: Whitespace character (space, tab, newline, etc.).
    • \S: Non-whitespace.
    • \w: Word character (alphanumeric + underscore: a-zA-Z0-9_).
    • \W: Non-word character.
    • .: Any character (except newline, unless s flag is used).
  • Unicode: Flag "u" and Class \p{...}:
    • u flag: Essential for correct handling of Unicode characters outside the BMP (surrogate pairs). Without u, . might match half a surrogate pair, and \w might not match all letters.
    • \p{UnicodeProperty} (with u flag): Matches characters with a specific Unicode property. E.g., \p{L} (any Unicode letter), \p{N} (any Unicode number), \p{Script=Cyrillic}.
  • Anchors: String Start ^ and End $:
    • ^: Matches the beginning of the input string.
    • $: Matches the end of the input string.
  • Multiline Mode of Anchors ^ $, Flag "m":
    • With m flag, ^ matches the start of a line (after \n or string start).
    • With m flag, $ matches the end of a line (before \n or string end).
    • Without m, ^ and $ only match the absolute start and end of the entire string.
  • Word Boundary: \b:
    • Matches a position where a word character (\w) is not followed by a word character, or vice-versa. Effectively, the boundary between \w and \W (or string start/end).
    • Example: /\bcat\b/ matches "cat" in "The cat sat", but not in "catapult".
    • \B: Non-word boundary.
  • Escaping, Special Characters:
    • Special characters in regex have specific meanings: [] {} () \ . ^ $ * + ? |.
    • To match them literally, escape them with a backslash: \., \+, \(, etc.
    • Backslash \ itself needs to be escaped in string literals (e.g., new RegExp('\\.')).
  • Sets and Ranges [...]:
    • [abc]: Matches any single character from the set a, b, or c.
    • [a-z]: Matches any single character in the range a to z.
    • [0-9A-Za-z]: Matches any alphanumeric character.
    • [^abc]: Matches any single character not in the set a, b, or c. (Negated character set).
  • Quantifiers +, *, ? and {n}:
    • +: One or more times (e.g., a+ matches "a", "aa", "aaa").
    • *: Zero or more times (e.g., a* matches "", "a", "aa", "aaa").
    • ?: Zero or one time (e.g., a? matches "" or "a").
    • {n}: Exactly n times (e.g., a{3} matches "aaa").
    • {n,}: n or more times (e.g., a{3,} matches "aaa", "aaaa").
    • {n,m}: Between n and m times, inclusive (e.g., a{3,5} matches "aaa", "aaaa", "aaaaa").
  • Greedy and Lazy Quantifiers:
    • Greedy (default): Quantifiers try to match the longest possible string. (e.g., .* in <a> ... </a> matches everything between first <a> and last </a>).
    • Lazy (non-greedy): Add ? after the quantifier (e.g., +?, *?, ??, {n,}?, {n,m}?). They try to match the shortest possible string.
    • Example: <.*?> in <p><b>Hello</b> <i>World</i></p> matches <b>Hello</b> instead of the entire string.
  • Capturing Groups:
    • (pattern): Groups parts of a pattern. The matched content of a capturing group can be accessed later.
    • Numbered groups: (1), (2), etc., based on their order.
    • Named groups: (?<name>pattern) (e.g., (?<year>\d{4})). Access via match.groups.name.
    • Non-capturing groups: (?:pattern). Groups for matching but don't capture content.
  • Backreferences in Pattern: \N and \k<name>:
    • \N: Matches the content previously captured by the N-th capturing group (e.g., (a)\1 matches "aa").
    • \k<name>: Matches the content previously captured by the named group name (e.g., (?<word>\w+)\k<word>).
  • Alternation (OR) |:
    • pattern1|pattern2: Matches either pattern1 or pattern2.
    • Parentheses are often used to group alternatives: (cat|dog)s matches "cats" or "dogs".
  • Lookahead and Lookbehind:
    • Lookahead ((?=...), (?!...)): Matches a position (zero-width assertion) where a pattern is (positive lookahead) or is not (negative lookahead) followed by another pattern.
      • x(?=y): Matches x only if x is followed by y.
      • x(?!y): Matches x only if x is not followed by y.
    • Lookbehind ((?<=...), (?<!...)): Matches a position where a pattern is (positive lookbehind) or is not (negative lookbehind) preceded by another pattern. (Requires ES2018+ support).
      • (?<=y)x: Matches x only if x is preceded by y.
      • (?<!y)x: Matches x only if x is not preceded by y.
    • Use Cases: Complex validation, parsing where context is important but not part of the match.
  • Catastrophic Backtracking:
    • A performance issue where a regex engine takes an extremely long time to evaluate a pattern, often due to ambiguous quantifiers, nested quantifiers, or greedy matching.
    • Example: (a+)+s trying to match aaaaaaaaaaaaaaaaaaax. The (a+)+ has many ways to split as, causing the engine to backtrack excessively.
    • Prevention: Use lazy quantifiers, possessive quantifiers (not in JS), rephrase patterns to reduce ambiguity, avoid nested quantifiers.
  • Sticky Flag "y", Searching at Position:
    • y (sticky) flag: Ensures the regex only matches from the position indicated by lastIndex property of the RegExp object.
    • regex.exec(string): When y flag is set, exec will only match if the match starts exactly at regex.lastIndex. If a match is found, lastIndex is updated to the end of the match. If no match, lastIndex is reset to 0.
    • Use Cases: Parsing string data in chunks, sequential tokenizing.
  • Methods of RegExp and String:
    • RegExp methods:
      • regex.test(string): Returns true if regex finds a match in string, false otherwise.
      • regex.exec(string): Returns an array with match info ([fullMatch, group1, ...]) and properties (index, input, groups), or null if no match. Useful for iterating with g or y flags.
    • String methods (that use RegExp):
      • str.match(regex):
        • If g flag: Returns an array of all full matches.
        • No g flag: Returns array like regex.exec().
      • str.matchAll(regex): Returns an iterator for all matches, including capturing groups. Requires g flag.
      • str.search(regex): Returns the index of the first match, or -1. Ignores g flag.
      • str.replace(regex, replacement): Replaces matches. replacement can be a string or a function.
      • str.split(regex): Splits a string by regex pattern.

Related Posts