javascript
examples
examples.jsβ‘javascript
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// β ES MODULES SYNTAX β
// β Modern JavaScript Module System β
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ES MODULES OVERVIEW β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ES Modules (ESM) = Native JavaScript module system (ES2015+) β
β β
β ββββββββββββββββ import/export ββββββββββββββββ β
β β module.js β βββββββββββββββββββΊ β main.js β β
β β β β β β
β β export β β import β β
β β functions, β β what you β β
β β classes, β β need β β
β β variables β β β β
β ββββββββββββββββ ββββββββββββββββ β
β β
β Key Features: β
β β’ Static structure (analyzed at compile time) β
β β’ Tree-shakeable (dead code elimination) β
β β’ Asynchronous loading β
β β’ Strict mode by default β
β β’ Own scope (no global pollution) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 1. NAMED EXPORTS
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NAMED EXPORTS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Export specific named bindings that consumers import by exact name β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Inline Export β Export List β β
β βββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ€ β
β β export const PI = 3.14159; β const PI = 3.14159; β β
β β export function add(a, b) {...} β function add(a, b) {...} β β
β β export class Calculator {...} β export { PI, add, Calculator }; β β
β βββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// --- Inline Named Exports ---
// Each declaration can be exported individually
export const PI = 3.14159;
export const E = 2.71828;
export const GOLDEN_RATIO = 1.61803;
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export function multiply(a, b) {
return a * b;
}
export function divide(a, b) {
if (b === 0) throw new Error('Division by zero');
return a / b;
}
export class Calculator {
constructor() {
this.result = 0;
}
add(n) {
this.result += n;
return this;
}
subtract(n) {
this.result -= n;
return this;
}
multiply(n) {
this.result *= n;
return this;
}
divide(n) {
if (n === 0) throw new Error('Division by zero');
this.result /= n;
return this;
}
clear() {
this.result = 0;
return this;
}
getResult() {
return this.result;
}
}
// --- Export List (Bottom of File) ---
// Define first, export later
const VERSION = '1.0.0';
const AUTHOR = 'JavaScript Module';
function power(base, exponent) {
return Math.pow(base, exponent);
}
function squareRoot(n) {
if (n < 0) throw new Error('Cannot calculate square root of negative number');
return Math.sqrt(n);
}
// Export list at bottom of file
export { VERSION, AUTHOR, power, squareRoot };
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 2. RENAMING EXPORTS
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RENAMING EXPORTS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Use 'as' keyword to export under different names β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β // Internal name β External name β β
β β export { internalName as publicName } β β
β β β β
β β // Example: β β
β β function calculateSum(arr) {...} β β
β β export { calculateSum as sum } // Exported as 'sum' β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Internal function names (more descriptive)
function calculateArithmeticMean(numbers) {
const sum = numbers.reduce((acc, n) => acc + n, 0);
return sum / numbers.length;
}
function calculateStandardDeviation(numbers) {
const mean = calculateArithmeticMean(numbers);
const squaredDiffs = numbers.map((n) => Math.pow(n - mean, 2));
return Math.sqrt(calculateArithmeticMean(squaredDiffs));
}
function calculateFactorial(n) {
if (n < 0) throw new Error('Factorial not defined for negative numbers');
if (n <= 1) return 1;
return n * calculateFactorial(n - 1);
}
// Export with shorter, public-facing names
export {
calculateArithmeticMean as mean,
calculateStandardDeviation as stdDev,
calculateFactorial as factorial,
};
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 3. DEFAULT EXPORTS
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DEFAULT EXPORTS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Each module can have ONE default export β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β // Exporting β // Importing β β
β ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ€ β
β β export default function() {} β import anyName from './module' β β
β β export default class {} β // No braces needed! β β
β β export default expression; β // Can use any name β β
β ββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ β
β β
β Default Export vs Named Export: β
β ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββ β
β β Default β Named β β
β ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β One per module β Multiple per module β β
β β Import without braces β Import with braces β β
β β Any import name β Must match export name (or use 'as') β β
β β For "main" thing β For utilities, constants, helpers β β
β ββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Example: Default export a class
class MathUtility {
static add(a, b) {
return a + b;
}
static subtract(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;
}
static power(base, exp) {
return Math.pow(base, exp);
}
static sqrt(n) {
return Math.sqrt(n);
}
static abs(n) {
return Math.abs(n);
}
static round(n, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.round(n * factor) / factor;
}
}
// NOTE: In a real file, you'd use: export default MathUtility;
// Can't use in same file with other examples, showing syntax only
// Default export can be anonymous
// export default function(a, b) { return a + b; }
// export default class { constructor() {} }
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 4. MIXED EXPORTS (Default + Named)
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MIXED EXPORTS (Default + Named) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Combine default and named exports in one module β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β // Module: lodash-like utility library β β
β β β β
β β // Default export: main utility object β β
β β export default { β β
β β chunk, compact, flatten β β
β β }; β β
β β β β
β β // Named exports: individual functions β β
β β export { chunk, compact, flatten }; β β
β β β β
β β // Importing: β β
β β import _ from 'lodash'; // Default β β
β β import { chunk } from 'lodash'; // Named β β
β β import _, { chunk } from 'lodash'; // Both β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Utility functions
export function chunk(array, size) {
const result = [];
for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size));
}
return result;
}
export function compact(array) {
return array.filter(Boolean);
}
export function flatten(array, depth = 1) {
return array.flat(depth);
}
export function uniq(array) {
return [...new Set(array)];
}
export function groupBy(array, key) {
return array.reduce((result, item) => {
const groupKey = typeof key === 'function' ? key(item) : item[key];
(result[groupKey] = result[groupKey] || []).push(item);
return result;
}, {});
}
// In a real module file:
// export default { chunk, compact, flatten, uniq, groupBy };
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 5. IMPORT SYNTAX
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β IMPORT SYNTAX β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β IMPORT TYPE β SYNTAX β β
β βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β Named imports β import { a, b } from './module.js' β β
β β Renamed import β import { a as alias } from './module.js' β β
β β Default import β import MyDefault from './module.js' β β
β β Default + Named β import Def, { a, b } from './module.js' β β
β β Namespace import β import * as Module from './module.js' β β
β β Side-effect only β import './module.js' β β
β βββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// These are examples of import syntax (would be at top of file normally):
/*
// Named imports - import specific exports
import { add, subtract, multiply } from './math.js';
// Rename on import to avoid conflicts
import { add as addNumbers, subtract as subtractNumbers } from './math.js';
// Default import - can use any name
import Calculator from './calculator.js';
import Calc from './calculator.js'; // Same thing, different name
// Default + Named together
import Calculator, { add, PI } from './calculator.js';
// Namespace import - all exports as object
import * as MathUtils from './math.js';
// Usage: MathUtils.add(1, 2), MathUtils.PI
// Side-effect import (runs module code, no bindings)
import './polyfills.js';
import './styles.css'; // Common in bundlers
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 6. DYNAMIC IMPORTS
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DYNAMIC IMPORTS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Load modules on demand using import() function β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Static Import (Top of file) β Dynamic Import (Runtime) β β
β βββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ€ β
β β import { fn } from './mod.js' β const mod = await import('./mod.js')β β
β β β mod.fn() β β
β β β’ Loaded before execution β β’ Loaded when needed β β
β β β’ Always at top level β β’ Can be conditional β β
β β β’ Synchronous hoisting β β’ Returns Promise β β
β β β’ Better for tree-shaking β β’ Code-splitting friendly β β
β βββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββ β
β β
β Use Cases: β
β β’ Lazy loading (load when needed) β
β β’ Conditional loading (based on user action) β
β β’ Route-based code splitting β
β β’ Feature detection loading β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Dynamic import example - Lazy loading
export async function loadMathModule() {
console.log('Loading math module on demand...');
// import() returns a Promise
const mathModule = await import('./math.js');
// Access exports from the module
console.log('PI:', mathModule.PI);
console.log('Add:', mathModule.add(2, 3));
return mathModule;
}
// Conditional loading based on feature
export async function loadPolyfill() {
// Only load if browser doesn't support feature
if (!Array.prototype.flat) {
const { flat } = await import('./polyfills/array-flat.js');
Array.prototype.flat = flat;
}
}
// Route-based code splitting
export async function loadRoute(routeName) {
const routes = {
home: () => import('./pages/home.js'),
about: () => import('./pages/about.js'),
contact: () => import('./pages/contact.js'),
dashboard: () => import('./pages/dashboard.js'),
};
const loader = routes[routeName];
if (!loader) {
throw new Error(`Unknown route: ${routeName}`);
}
const module = await loader();
return module.default; // Assuming default export is the component
}
// Error handling with dynamic imports
export async function safeImport(modulePath) {
try {
const module = await import(modulePath);
return { success: true, module };
} catch (error) {
console.error(`Failed to load module: ${modulePath}`, error);
return { success: false, error };
}
}
// Dynamic import with destructuring
export async function loadUtilities() {
// Destructure directly from dynamic import
const { add, subtract, multiply, divide } = await import('./math.js');
return { add, subtract, multiply, divide };
}
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 7. RE-EXPORTS (Aggregating Modules)
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RE-EXPORTS (Barrel Files) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Re-export from other modules without importing locally β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β // utils/index.js (barrel file) β β
β β β β
β β // Re-export everything from another module β β
β β export * from './math.js'; β β
β β β β
β β // Re-export specific items β β
β β export { format, parse } from './date.js'; β β
β β β β
β β // Re-export with rename β β
β β export { format as formatDate } from './date.js'; β β
β β β β
β β // Re-export default as named β β
β β export { default as Calculator } from './Calculator.js'; β β
β β β β
β β // Re-export as namespace β β
β β export * as StringUtils from './strings.js'; β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Benefits: β
β β’ Single entry point for multiple modules β
β β’ Cleaner import paths β
β β’ Encapsulate internal structure β
β β’ Easy to reorganize internals β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Example: Barrel file structure
/*
// File: utils/index.js
// Re-export all from math module
export * from './math.js';
// Re-export specific functions from string utils
export { capitalize, trim, truncate } from './string.js';
// Re-export with renaming to avoid conflicts
export { format as formatDate } from './date.js';
export { format as formatNumber } from './number.js';
// Re-export default export as named export
export { default as Logger } from './Logger.js';
export { default as Config } from './Config.js';
// Re-export as namespace (ES2020+)
export * as ArrayUtils from './array.js';
export * as ObjectUtils from './object.js';
// Now consumers can import from single path:
// import { add, subtract, capitalize, Logger, ArrayUtils } from './utils';
*/
// Simulated barrel file exports
export const utilsVersion = '2.0.0';
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 8. MODULE FEATURES & BEHAVIORS
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ES MODULE FEATURES & BEHAVIORS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Feature β Behavior β β
β βββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β Strict Mode β Always enabled (no need for 'use strict') β β
β β Top-level this β undefined (not window/global) β β
β β Scope β Module scope (not global) β β
β β Execution β Deferred (after HTML parsing) β β
β β Singleton β Cached after first load β β
β β Live Bindings β Imports are live references β β
β β Hoisting β Imports hoisted to top β β
β β CORS β Required for cross-origin modules β β
β βββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Live bindings demonstration
let counter = 0;
export function getCounter() {
return counter;
}
export function incrementCounter() {
counter++;
return counter;
}
// When imported, getCounter() will always return current value
// This is because ES modules use "live bindings"
/*
// In another file:
import { getCounter, incrementCounter } from './counter.js';
console.log(getCounter()); // 0
incrementCounter();
console.log(getCounter()); // 1 (live binding reflects change)
*/
// Module singleton demonstration
export const moduleState = {
initialized: false,
data: null,
init(data) {
if (this.initialized) {
console.log('Module already initialized');
return;
}
this.data = data;
this.initialized = true;
console.log('Module initialized with:', data);
},
};
// This state is shared across ALL imports of this module
// (modules are cached and executed only once)
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 9. BROWSER MODULE USAGE
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BROWSER MODULE USAGE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Using ES Modules in HTML: β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β <!-- Module script --> β β
β β <script type="module" src="main.js"></script> β β
β β β β
β β <!-- Inline module --> β β
β β <script type="module"> β β
β β import { add } from './math.js'; β β
β β console.log(add(2, 3)); β β
β β </script> β β
β β β β
β β <!-- Fallback for older browsers --> β β
β β <script nomodule src="fallback.js"></script> β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Module vs Classic Script: β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β <script> β <script type="module"> β β
β ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β Global scope β Module scope β β
β β Executed immediatelyβ Deferred by default β β
β β Blocks parsing β Doesn't block β β
β β Can access window β this = undefined β β
β β No CORS required β CORS required β β
β β Classic variables β Strict mode β β
β ββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 10. PRACTICAL PATTERNS
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PRACTICAL PATTERNS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Common module organization patterns in real projects β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Pattern 1: Feature module with types
export const UserModule = {
// Types/Constants
ROLES: {
ADMIN: 'admin',
USER: 'user',
GUEST: 'guest',
},
// Factory function
createUser(name, role = 'user') {
return {
id: Date.now(),
name,
role,
createdAt: new Date(),
};
},
// Validation
isValid(user) {
return (
user &&
typeof user.name === 'string' &&
Object.values(this.ROLES).includes(user.role)
);
},
// Serialization
toJSON(user) {
return JSON.stringify(user);
},
fromJSON(json) {
return JSON.parse(json);
},
};
// Pattern 2: Service module
export const ApiService = {
baseURL: 'https://api.example.com',
async get(endpoint) {
const response = await fetch(`${this.baseURL}${endpoint}`);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return response.json();
},
async post(endpoint, data) {
const response = await fetch(`${this.baseURL}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return response.json();
},
};
// Pattern 3: Configuration module
export const Config = Object.freeze({
APP_NAME: 'My Application',
VERSION: '1.0.0',
API_URL: 'https://api.example.com',
DEBUG: process.env?.NODE_ENV !== 'production',
features: Object.freeze({
darkMode: true,
notifications: true,
analytics: true,
}),
});
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 11. IMPORT ASSERTIONS (FUTURE)
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β IMPORT ASSERTIONS (Emerging Feature) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Specify expected module type for security and clarity: β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β // JSON import (requires assertion) β β
β β import data from './data.json' assert { type: 'json' }; β β
β β β β
β β // CSS import β β
β β import styles from './styles.css' assert { type: 'css' }; β β
β β β β
β β // Dynamic import with assertion β β
β β const config = await import('./config.json', { β β
β β assert: { type: 'json' } β β
β β }); β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Note: Syntax may change. Currently using 'with' keyword in some browsers: β
β import data from './data.json' with { type: 'json' }; β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// 12. COMPLETE MODULE EXAMPLE
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β COMPLETE MODULE EXAMPLE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β A complete, production-ready module structure β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// βββ EventEmitter Module βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Private via closure (not exported)
const privateListeners = new WeakMap();
// Named export: EventEmitter class
export class EventEmitter {
constructor() {
privateListeners.set(this, new Map());
}
on(event, callback) {
const listeners = privateListeners.get(this);
if (!listeners.has(event)) {
listeners.set(event, new Set());
}
listeners.get(event).add(callback);
return this;
}
off(event, callback) {
const listeners = privateListeners.get(this);
if (listeners.has(event)) {
listeners.get(event).delete(callback);
}
return this;
}
emit(event, ...args) {
const listeners = privateListeners.get(this);
if (listeners.has(event)) {
for (const callback of listeners.get(event)) {
callback(...args);
}
}
return this;
}
once(event, callback) {
const onceWrapper = (...args) => {
this.off(event, onceWrapper);
callback(...args);
};
return this.on(event, onceWrapper);
}
}
// Named export: helper functions
export function createEventEmitter() {
return new EventEmitter();
}
// Named export: constants
export const COMMON_EVENTS = {
READY: 'ready',
ERROR: 'error',
DATA: 'data',
COMPLETE: 'complete',
};
// If this were the main module file, we'd add:
// export default EventEmitter;
console.log(`
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ES MODULES SYNTAX - EXAMPLES COMPLETE β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β β
β Covered Topics: β
β β Named exports (inline & list) β
β β Renaming exports β
β β Default exports β
β β Mixed exports β
β β Import syntax variations β
β β Dynamic imports β
β β Re-exports & barrel files β
β β Module features & behaviors β
β β Browser usage β
β β Practical patterns β
β β Import assertions β
β β
β Remember: β
β β’ Use .js extension in imports (for browsers) β
β β’ Modules are strict mode by default β
β β’ Imports are hoisted β
β β’ Modules are singletons (cached) β
β β’ Exports are live bindings β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
`);