JavaScript 完全指南

NOTE

本文档最后更新于 2026年4月,涵盖 JavaScript 2026 新特性、异步编程、模块系统、Event Loop 及在 AI 编程中的定位。


目录

  1. JavaScript 概述
  2. JavaScript 2026 新特性
  3. ESM vs CJS 对比
  4. Event Loop 机制
  5. 异步编程模式
  6. Node.js 生态
  7. 浏览器 API
  8. TypeScript 关系
  9. AI 编程中的 JavaScript
  10. 实战技巧

JavaScript 概述

JavaScript 的地位

JavaScript 是 Web 开发的基石,从简单的表单验证脚本发展到如今的全栈编程语言:

平台JavaScript 角色运行环境
浏览器唯一原生语言V8/SpiderMonkey/JavaScriptCore
Node.js服务端编程V8
Deno现代运行时V8
边缘计算Cloudflare WorkersV8
移动端React Native/ExpoJavaScriptCore
桌面端Electron/TauriV8
ServerlessAWS Lambda/云函数多种运行时

JavaScript 引擎

引擎开发者使用环境
V8GoogleChrome, Node.js, Deno
SpiderMonkeyMozillaFirefox
JavaScriptCoreAppleSafari, React Native
ChakraMicrosoft旧版 Edge

语言特点

特点说明
动态类型类型在运行时确定
原型继承基于原型链的 OO
函数式特性一等公民函数,闭包
异步编程Promise, async/await
单线程Event Loop 驱动
多范式OOP/FP/命令式

JavaScript 2026 新特性

TC39 提案阶段

阶段说明示例功能
Stage 0稻草人提案尚未正式讨论
Stage 1提案探索阶段
Stage 2草案初始规范
Stage 3候选接近完成,等待实现
Stage 4完成已添加到标准

2026 年已完成特性

1. Array grouping(数组分组):

// Object.groupBy(稳定)
const inventory = [
  { name: 'asparagus', type: 'vegetables' },
  { name: 'bananas', type: 'fruit' },
  { name: 'goat', type: 'meat' }
];
 
const grouped = Object.groupBy(inventory, item => item.type);
// {
//   vegetables: [{ name: 'asparagus', type: 'vegetables' }],
//   fruit: [{ name: 'bananas', type: 'fruit' }],
//   meat: [{ name: 'goat', type: 'meat' }]
// }
 
// Map.groupBy
const groupedMap = Map.groupBy(inventory, item => item.type);

2. Array find from last(从后查找):

const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 2 }];
 
array.findLast(item => item.id === 2);  // { id: 2 } (最后一个)
array.findLastIndex(item => item.id === 2);  // 3

3. Shadow Realm(影子域):

const realm = new ShadowRealm();
 
// 隔离的全局作用域
const insideValue = realm.evaluate('42');
const result = realm.evaluate(`
  globalThis.add = (a, b) => a + b;
  globalThis.add(2, 3);
`);  // 5
 
realm.evaluate('globalThis.someAPI = {...}');

4. Iterator Helpers(迭代器助手):

function* generate() {
  yield 1;
  yield 2;
  yield 3;
}
 
const iter = generate();
 
iter.map(x => x * 2).filter(x => x > 2).toArray();  // [4, 6]

Stage 3 候选特性

1. Decorators(装饰器):

// 类装饰器
function logged(target, context) {
  console.log(`Class ${context.name} defined`);
  return target;
}
 
// 方法装饰器
function debounce(ms) {
  return function (target, context) {
    return function (...args) {
      // 防抖逻辑
    };
  };
}
 
// 属性装饰器
function readonly(_, context) {
  return {
    init() { return 42; }
  };
}
 
@logged
class MyClass {
  @readonly
  count = 0;
 
  @debounce(300)
  handleClick() { }
}

2. Explicit Resource Management(显式资源管理):

// using 声明(类似 Python with)
using file = await openFile('test.txt');
using stream = createWritableStream('output');
 
using { handle, cleanup } = acquireResource();
 
// Suppressor 符号
using timer = new Timer();
await timer.start();
 
// 结束时自动清理

3. Float16Array(Float16 数组):

const float16 = new Float16Array([1, 2, 3, 4]);
const float16Values = Float16Array.of(1.5, 2.5, 3.5);
 
// 与 WebGPU/ML 配合
const model = new Model();
model.setWeights(float16Data);

ESM vs CJS 对比

模块系统发展

系统全称引入版本文件扩展
CJSCommonJSNode.js 0.x.js, .cjs
AMDAsync Module DefinitionRequireJS.js
UMDUniversal Module Definition第三方.js
ESMECMAScript ModulesES2015/Node 14.mjs, .js

CommonJS 语法

// 导出
module.exports = { name: 'MyModule' };
module.exports.MyClass = class { };
 
// 或者
exports.myFunction = function() { };
exports.myValue = 42;
 
// 导入
const MyModule = require('./MyModule');
const { myFunction } = require('./utils');
 
// 动态 require
const moduleName = 'fs';
const fs = require(moduleName);

ESM 语法

// 命名导出
export const myValue = 42;
export function myFunction() { }
export class MyClass { }
 
// 默认导出
export default class { }
 
// 导入
import MyClass from './MyModule.js';
import { myValue, myFunction } from './utils.js';
import * as utils from './utils.js';
import { myValue as value } from './utils.js';
 
// 动态导入
const module = await import('./dynamic.js');

核心差异对比

维度ESMCJS
语法import/exportrequire/module.exports
加载时机静态(编译时解析)动态(运行时解析)
循环引用支持(可能有 undefined)支持(慎用)
Tree shaking支持不支持
异步加载支持(import())不支持
浏览器支持原生支持需打包
Node.js 支持需要 .mjs"type": "module"原生支持
严格模式默认启用可选

互操作性

// ESM 中使用 CJS 模块
import fs from 'fs';  // 自动包装为 ESM
import { readFile } from 'fs';  // 命名导入
 
// CJS 中使用 ESM 模块(需要动态 import)
const { default: myModule } = await import('./esm-module.mjs');
const { namedExport } = await import('./esm-module.mjs');

导入断言

// JSON 模块导入
import config from './config.json' assert { type: 'json' };
 
// 使用 with 语法(新版)
import config from './config.json' with { type: 'json' };
 
// CSS 模块(特定环境)
import styles from './styles.css' assert { type: 'css' };

Event Loop 机制

JavaScript 单线程模型

JavaScript 是单线程语言,通过 Event Loop 实现非阻塞异步操作:

┌─────────────────────────────────────────┐
│                  Stack                   │
│         (执行上下文/调用栈)               │
│                                          │
│  ┌────────────────────────────────────┐ │
│  │  function foo() {                   │ │
│  │    console.log(1);                  │ │
│  │    bar();  ← 调用 bar()             │ │
│  │    console.log(3);                  │ │
│  │  }                                  │ │
│  └────────────────────────────────────┘ │
└─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────┐
│               Heap                       │
│           (对象/内存分配)                 │
│                                          │
│  ┌────────────────────────────────────┐ │
│  │  { name: 'Alice', age: 30 }        │ │
│  │  [1, 2, 3, 4, 5]                  │ │
│  │  function add(a, b) { ... }       │ │
│  └────────────────────────────────────┘ │
└─────────────────────────────────────────┘

Event Loop 流程

                    ┌──────────────────────┐
                    │       Call Stack     │
                    └──────────┬───────────┘
                               │
                    ┌──────────▼───────────┐
                    │    Microtask Queue    │
                    │  (Promise.then,      │
                    │   queueMicrotask)    │
                    └──────────┬───────────┘
                               │
          ┌────────────────────┼────────────────────┐
          │                    │                    │
┌─────────▼─────────┐ ┌────────▼────────┐ ┌────────▼────────┐
│   setTimeout       │ │  I/O Callbacks │ │  Check Phase   │
│   setInterval      │ │  (文件/网络)    │ │  setImmediate │
└───────────────────┘ └─────────────────┘ └────────────────┘
          │                    │                    │
          └────────────────────┼────────────────────┘
                               │
                    ┌──────────▼───────────┐
                    │    Macrotask Queue    │
                    │  (setTimeout,        │
                    │   setInterval,      │
                    │   I/O)              │
                    └─────────────────────┘

执行顺序示例

console.log('1');           // 同步
 
setTimeout(() => console.log('2'), 0);  // Macrotask
 
Promise.resolve()
  .then(() => console.log('3'));  // Microtask
 
queueMicrotask(() => console.log('4'));  // Microtask
 
console.log('5');           // 同步
 
// 输出顺序:1, 5, 3, 4, 2

浏览器 vs Node.js Event Loop

阶段浏览器Node.js
1执行同步代码执行同步代码
2执行所有微任务执行所有微任务
3渲染(如果需要)timers (setTimeout/setInterval)
4执行宏任务pending callbacks
5-idle, prepare
6-poll (retrieve new I/O events)
7-check (setImmediate)
8-close callbacks

Node.js 特殊 API

// setImmediate vs setTimeout
setImmediate(() => console.log('immediate'));
setTimeout(() => console.log('timeout'), 0);
// 顺序不确定,取决于 I/O 状态
 
// process.nextTick(最高优先级微任务)
Promise.resolve().then(() => console.log('promise'));
process.nextTick(() => console.log('nextTick'));
// 输出: nextTick, promise
 
// 排队机制
function recursive() {
  queueMicrotask(recursive);
  // 不会导致栈溢出
}

异步编程模式

回调模式(传统)

// 回调地狱
fetchData(url, (err, data) => {
  if (err) {
    handleError(err);
    return;
  }
 
  processData(data, (err, result) => {
    if (err) {
      handleError(err);
      return;
    }
 
    saveResult(result, (err, saved) => {
      if (err) {
        handleError(err);
        return;
      }
 
      sendNotification(saved, (err) => {
        if (err) handleError(err);
      });
    });
  });
});

Promise 模式

// 链式调用
fetchData(url)
  .then(data => processData(data))
  .then(result => saveResult(result))
  .then(saved => sendNotification(saved))
  .catch(handleError)
  .finally(() => cleanup());
 
// Promise.all - 并行执行
const [users, posts, comments] = await Promise.all([
  fetchUsers(),
  fetchPosts(),
  fetchComments()
]);
 
// Promise.allSettled - 所有都执行完毕
const results = await Promise.allSettled([
  fetchData1(),
  fetchData2(),
  fetchData3()
]);
 
results.forEach((result, index) => {
  if (result.status === 'fulfilled') {
    console.log(`Data ${index}:`, result.value);
  } else {
    console.log(`Error ${index}:`, result.reason);
  }
});
 
// Promise.race - 竞速
const result = await Promise.race([
  fetchWithTimeout(url1, 1000),
  fetchWithTimeout(url2, 1000)
]);

async/await 模式

// 基本用法
async function fetchAndProcess(url) {
  try {
    const data = await fetchData(url);
    const processed = await processData(data);
    return processed;
  } catch (error) {
    handleError(error);
    throw error;
  }
}
 
// 并行执行优化
async function fetchAll() {
  // 错误方式:顺序执行
  const a = await fetchA();  // 等待 100ms
  const b = await fetchB();  // 等待 100ms
  // 总计 200ms
 
  // 正确方式:并行执行
  const [a, b] = await Promise.all([fetchA(), fetchB()]);
  // 总计 100ms
}
 
// 条件并行
const [user, posts] = await Promise.all([
  hasUserId ? fetchUser(userId) : null,
  fetchPosts()
]);

异步迭代器

// AsyncIterator
async function* asyncGenerator() {
  let i = 0;
  while (i < 10) {
    await new Promise(resolve => setTimeout(resolve, 100));
    yield i++;
  }
}
 
// 使用 for await...of
for await (const value of asyncGenerator()) {
  console.log(value);
}
 
// 处理流式数据
async function processStream(url) {
  const response = await fetch(url);
  const reader = response.body.getReader();
 
  const decoder = new TextDecoder();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    console.log(decoder.decode(value));
  }
}

Node.js 生态

包管理器对比

特性npmpnpmyarn
安装速度中等最快
磁盘占用中等
node_modules扁平隔离扁平/PnP
lockfilepackage-lock.jsonpnpm-lock.yamlyarn.lock
幽灵依赖
monorepoworkspacesworkspaceworkspace

常用命令

# npm
npm install package          # 安装
npm install -D package       # 开发依赖
npm install package@version  # 指定版本
npm update                  # 更新
npm audit                   # 安全审计
npm run build               # 运行脚本
 
# pnpm
pnpm add package            # 安装
pnpm add -D package         # 开发依赖
pnpm install                # 从 lockfile 安装
pnpm update                 # 更新
 
# yarn
yarn add package            # 安装
yarn add -D package         # 开发依赖
yarn install                # 安装
yarn upgrade               # 更新

常用全局工具

工具功能npm 包
npx运行本地包npm 内置
ts-node运行 TypeScriptts-node
tsx快速运行 TStsx
nodemon开发热重载nodemon
rimraf跨平台删除rimraf
pnpm包管理器pnpm

Node.js 核心模块

模块功能
fs文件系统操作
path路径处理
http/httpsHTTP 服务器/客户端
crypto加密功能
events事件发射器
stream流处理
buffer二进制数据
urlURL 解析
querystring查询字符串
os操作系统信息
util工具函数
child_process子进程
cluster集群
worker_threads工作线程

常用第三方模块

类别模块说明
Web 框架express, koa, fastifyHTTP 服务器
全栈框架next, nuxt, remixSSR 框架
数据库prisma, mongoose, sequelizeORM
验证zod, joi, class-validator数据验证
日期dayjs, date-fns, luxon日期处理
工具lodash, ramda函数式工具
颜色chalk, picocolors终端颜色
日志winston, pino日志库

浏览器 API

Fetch API

// 基本 GET 请求
const response = await fetch('https://api.example.com/data');
const data = await response.json();
 
// 带参数
const params = new URLSearchParams({ page: 1, limit: 10 });
const response = await fetch(`https://api.example.com/data?${params}`);
 
// POST 请求
const response = await fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token'
  },
  body: JSON.stringify({ name: 'Alice', age: 30 })
});
 
// 处理错误
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
 
// 流式响应
const response = await fetch('https://api.example.com/stream');
const reader = response.body.getReader();
const decoder = new TextDecoder();
 
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value);
  // 处理数据块
}

WebSocket

// 连接
const ws = new WebSocket('wss://api.example.com/socket');
 
// 事件处理
ws.onopen = () => {
  console.log('Connected');
  ws.send(JSON.stringify({ type: 'subscribe', channel: 'news' }));
};
 
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};
 
ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};
 
ws.onclose = () => {
  console.log('Disconnected');
};
 
// 发送消息
ws.send(JSON.stringify({ message: 'Hello' }));
 
// 关闭连接
ws.close();

Intersection Observer

const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        console.log('Element visible:', entry.target);
        // 加载内容、发送分析等
      }
    });
  },
  {
    root: null,           // 视口
    rootMargin: '0px',    // 边距
    threshold: 0.1        // 10% 可见时触发
  }
);
 
// 观察元素
document.querySelectorAll('.lazy-load').forEach((el) => {
  observer.observe(el);
});
 
// 停止观察
observer.disconnect();

其他常用 API

// BroadcastChannel(同源通信)
const channel = new BroadcastChannel('my_channel');
channel.postMessage({ type: 'update', data: {...} });
channel.onmessage = (event) => { ... };
 
// ResizeObserver
const resizeObserver = new ResizeObserver((entries) => {
  entries.forEach((entry) => {
    const { width, height } = entry.contentRect;
    console.log(`Size: ${width}x${height}`);
  });
});
resizeObserver.observe(element);
 
// Navigator API
navigator.clipboard.writeText('Hello');           // 剪贴板
navigator.share({ title: 'Title', url: '...' }); // 分享
navigator.onLine;                                  // 在线状态
navigator.storage.estimate();                      // 存储配额
 
// Screen API
screen.width;         // 屏幕宽度
screen.height;        // 屏幕高度
screen.orientation;   // 方向
 
// Vibration API
navigator.vibrate([200, 100, 200]);  // 震动模式

TypeScript 关系

TypeScript 简介

TypeScript 是 JavaScript 的超集,添加了类型系统:

// JavaScript
function add(a, b) {
  return a + b;
}
add(1, 2);    // 3
add('a', 'b'); // 'ab'
add(1, 'b');  // '1b' (隐式转换)
// TypeScript
function add(a: number, b: number): number {
  return a + b;
}
add(1, 2);     // 3 ✓
add('a', 'b'); // Error ✓

类型推断与标注

// 类型推断(多数情况不需要显式标注)
let name = 'Alice';  // string
let age = 30;         // number
let isActive = true;  // boolean
 
// 显式标注
let name: string = 'Alice';
let age: number = 30;
let isActive: boolean = true;
 
// 函数标注
function greet(name: string): string {
  return `Hello, ${name}!`;
}
 
// 箭头函数
const add = (a: number, b: number): number => a + b;
 
// 可选参数
function createUser(name: string, age?: number): User {
  return { name, age };
}
 
// 默认参数
function greet(name: string = 'Guest'): string {
  return `Hello, ${name}!`;
}

泛型

// 泛型函数
function identity<T>(arg: T): T {
  return arg;
}
 
identity<string>('hello');  // string
identity(42);               // number(推断)
 
// 泛型接口
interface Container<T> {
  value: T;
  getValue(): T;
}
 
// 泛型约束
function getLength<T extends { length: number }>(arg: T): number {
  return arg.length;
}
 
getLength('hello');  // 5
getLength([1, 2, 3]); // 3
getLength({ length: 10 }); // 10

实用类型

// Partial - 所有属性可选
type PartialUser = Partial<User>;
 
// Required - 所有属性必需
type RequiredUser = Required<User>;
 
// Pick - 选择属性
type UserPreview = Pick<User, 'id' | 'name'>;
 
// Omit - 排除属性
type UserWithoutPassword = Omit<User, 'password'>;
 
// Record - 键值对
type UserMap = Record<string, User>;
 
// Exclude - 排除类型
type NonNull = Exclude<string | null | undefined, null | undefined>;
 
// Extract - 提取类型
type StringOnly = Extract<string | number | boolean, string>;
 
// ReturnType - 返回类型
type AddReturn = ReturnType<typeof add>;
 
// Parameters - 参数类型
type AddParams = Parameters<typeof add>;

AI 编程中的 JavaScript

AI 助手的 JavaScript 优势

  1. 语法简洁:相比 TypeScript,AI 更容易生成正确的 JavaScript
  2. 生态系统:npm 生态极其丰富
  3. 跨平台:浏览器/Node.js/边缘计算
  4. 动态性:快速原型和迭代
  5. 类型辅助:JSDoc 注释提供类型提示

JSDoc 类型注释

/**
 * @typedef {Object} User
 * @property {string} id
 * @property {string} name
 * @property {number} age
 * @property {string} [email]
 */
 
/**
 * 获取用户
 * @param {string} id - 用户 ID
 * @returns {Promise<User>} 用户对象
 */
async function getUser(id) {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
}
 
// @type 注解
/** @type {Map<string, User>} */
const userMap = new Map();
 
// @param 注解
/**
 * @param {string} name
 * @param {number} [age]
 */
function greet(name, age) {
  console.log(`Hello, ${name}!`);
  if (age !== undefined) {
    console.log(`You are ${age} years old.`);
  }
}

AI 生成代码示例

// AI Prompt: "用 JavaScript 实现一个防抖函数"
 
function debounce(func, wait) {
  let timeoutId;
 
  return function (...args) {
    clearTimeout(timeoutId);
 
    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}
 
// 使用
const handleInput = debounce((e) => {
  console.log('Input:', e.target.value);
  // 发送搜索请求
}, 300);
 
document.querySelector('input').addEventListener('input', handleInput);

实战技巧

性能优化

// 防抖
function debounce(fn, ms) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}
 
// 节流
function throttle(fn, ms) {
  let lastCall = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastCall >= ms) {
      lastCall = now;
      fn(...args);
    }
  };
}
 
// 记忆化
function memoize(fn) {
  const cache = new Map();
  return (...args) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}

数组操作技巧

// 去重
[...new Set([1, 2, 2, 3])];  // [1, 2, 3]
 
// 分组
Object.groupBy(items, item => item.category);
 
// 展平
[1, [2, [3]]].flat(2);  // [1, 2, 3]
[1, [2, [3]]].flatMap(x => x);  // [1, 2, [3]]
 
// 安全访问
const value = obj?.nested?.property ?? 'default';
 
// 条件执行
arr?.filter(x => x > 0)?.map(x => x * 2);
 
// 链式调用
const result = data
  ?.filter(x => x.active)
  ?.map(x => transform(x))
  ?.sort((a, b) => a.value - b.value);

错误处理

// try-catch-finally
async function fetchData() {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    console.error('Fetch error:', error);
    throw error;
  } finally {
    cleanup();
  }
}
 
// 自定义错误
class ValidationError extends Error {
  constructor(message, field) {
    super(message);
    this.name = 'ValidationError';
    this.field = field;
  }
}
 
// 全局错误处理
window.addEventListener('unhandledrejection', (event) => {
  console.error('Unhandled promise rejection:', event.reason);
});
 
window.addEventListener('error', (event) => {
  console.error('Global error:', event.error);
});

JavaScript 高级主题

代理与反射

// Proxy 基础用法
const handler = {
  get(target, prop) {
    console.log(`Getting ${prop}`);
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    console.log(`Setting ${prop} to ${value}`);
    return Reflect.set(target, prop, value);
  }
};
 
const obj = new Proxy({ name: 'Alice' }, handler);
console.log(obj.name); // 输出: Getting name, Alice
obj.age = 25; // 输出: Setting age to 25
 
// 响应式系统实现
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key);
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      trigger(target, key);
      return true;
    }
  });
}
 
// 表单验证器
const validator = new Proxy({}, {
  set(target, prop, value) {
    if (prop === 'email' && !value.includes('@')) {
      throw new TypeError('Invalid email');
    }
    target[prop] = value;
    return true;
  }
});

迭代器与生成器

// 自定义迭代器
class Range {
  constructor(start, end) {
    this.start = start;
    this.end = end;
    this.current = start;
  }
 
  [Symbol.iterator]() {
    return {
      current: this.start,
      end: this.end,
      next() {
        if (this.current <= this.end) {
          return { value: this.current++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
}
 
for (const num of new Range(1, 5)) {
  console.log(num); // 1, 2, 3, 4, 5
}
 
// 生成器函数
function* idGenerator() {
  let id = 1;
  while (true) {
    yield id++;
  }
}
 
const gen = idGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
 
// 异步生成器
async function* fetchPages(url) {
  let page = 1;
  while (page <= 10) {
    const data = await fetch(`${url}?page=${page}`);
    yield { page, data: await data.json() };
    page++;
  }
}

WeakMap、WeakSet 与内存管理

// 私有属性
const privateData = new WeakMap();
 
class User {
  constructor(name, password) {
    privateData.set(this, { name, password });
  }
 
  getName() {
    return privateData.get(this).name;
  }
 
  authenticate(pwd) {
    return privateData.get(this).password === pwd;
  }
}
 
// 缓存示例
const cache = new WeakMap();
function process(obj) {
  if (cache.has(obj)) {
    return cache.get(obj);
  }
  const result = expensiveComputation(obj);
  cache.set(obj, result);
  return result;
}
 
// WeakSet 用于对象标记
const registeredObjects = new WeakSet();
 
function register(obj) {
  if (registeredObjects.has(obj)) {
    console.log('Already registered');
    return false;
  }
  registeredObjects.add(obj);
  return true;
}

模块系统进阶

// 动态导入
const module = await import('./module.js');
module.default();
module.namedExport();
 
// 条件导入
const isNode = typeof window === 'undefined';
const utils = isNode 
  ? await import('./utils-node.js')
  : await import('./utils-browser.js');
 
// 模块合成
export { a, b } from './module.js';
export * from './module.js';
export { default as moduleName } from './module.js';
 
// Re-export 聚合器
// utils/index.js
export { add } from './math.js';
export { format } from './string.js';
export { parse } from './date.js';

装饰器提案(TC39 第三阶段)

// 类装饰器
function logClass(target) {
  console.log(`Class ${target.name} defined`);
  return target;
}
 
// 方法装饰器
function memoize(target, name, descriptor) {
  const original = descriptor.value;
  const cache = new Map();
  
  descriptor.value = function(...args) {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = original.apply(this, args);
    cache.set(key, result);
    return result;
  };
  return descriptor;
}
 
// 属性装饰器
function readonly(target, name, descriptor) {
  descriptor.writable = false;
  return descriptor;
}
 
@logClass
class Calculator {
  @memoize
  fibonacci(n) {
    return n <= 1 ? n : this.fibonacci(n-1) + this.fibonacci(n-2);
  }
  
  @readonly
  VERSION = '1.0.0';
}

尾递归优化

// 非优化版本
function factorial(n, acc = 1) {
  if (n <= 1) return acc;
  return factorial(n - 1, n * acc);
}
 
// trampoline 实现
function trampoline(fn) {
  return function(...args) {
    let result = fn(...args);
    while (typeof result === 'function') {
      result = result();
    }
    return result;
  };
}
 
function factorialTrampoline(n, acc = 1) {
  if (n <= 1) return acc;
  return () => factorialTrampoline(n - 1, n * acc);
}
 
const factorialOptimized = trampoline(factorialTrampoline);

JavaScript 与 AI 集成

Fetch API 与流式响应

// 流式文本处理
async function* streamText(response) {
  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    yield decoder.decode(value, { stream: true });
  }
}
 
// OpenAI 流式调用
async function* streamAI(prompt) {
  const response = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${API_KEY}`
    },
    body: JSON.stringify({
      model: 'gpt-4',
      messages: [{ role: 'user', content: prompt }],
      stream: true
    })
  });
  
  for await (const chunk of streamText(response)) {
    const lines = chunk.split('\n').filter(l => l.startsWith('data: '));
    for (const line of lines) {
      const data = JSON.parse(line.slice(6));
      const content = data.choices?.[0]?.delta?.content;
      if (content) yield content;
    }
  }
}

Service Worker 与离线 AI

// sw.js
const CACHE_NAME = 'ai-model-cache';
 
self.addEventListener('fetch', (event) => {
  if (event.request.url.includes('/api/')) {
    event.respondWith(networkFirst(event.request));
  }
});
 
async function networkFirst(request) {
  try {
    const response = await fetch(request);
    const cache = await caches.open(CACHE_NAME);
    cache.put(request, response.clone());
    return response;
  } catch {
    const cached = await caches.match(request);
    return cached || new Response('Offline');
  }
}

JavaScript 设计模式

模块模式

// 命名空间模式
const MyApp = MyApp || {};
 
MyApp.Utils = (function() {
  const _private = 'secret';
  
  function _formatDate(date) {
    return date.toISOString().split('T')[0];
  }
  
  return {
    formatDate: _formatDate,
    publicAPI: function() {
      return 'Public method';
    }
  };
})();
 
// ES Module 模式
export class DataStore {
  #items = new Map();
  
  add(key, value) {
    this.#items.set(key, value);
  }
  
  get(key) {
    return this.#items.get(key);
  }
  
  *[Symbol.iterator]() {
    for (const [key, value] of this.#items) {
      yield { key, value };
    }
  }
}
 
export default DataStore;

观察者与发布订阅

class EventEmitter {
  #events = new Map();
  
  on(event, listener) {
    if (!this.#events.has(event)) {
      this.#events.set(event, []);
    }
    this.#events.get(event).push(listener);
    return this;
  }
  
  off(event, listener) {
    if (this.#events.has(event)) {
      const listeners = this.#events.get(event);
      const index = listeners.indexOf(listener);
      if (index > -1) {
        listeners.splice(index, 1);
      }
    }
    return this;
  }
  
  emit(event, ...args) {
    if (this.#events.has(event)) {
      for (const listener of this.#events.get(event)) {
        listener(...args);
      }
    }
    return this;
  }
  
  once(event, listener) {
    const wrapper = (...args) => {
      listener(...args);
      this.off(event, wrapper);
    };
    return this.on(event, wrapper);
  }
}
 
// 使用
const emitter = new EventEmitter();
emitter.on('message', (data) => console.log('Message:', data));
emitter.emit('message', { text: 'Hello!' });

工厂与抽象工厂

// 工厂函数
function createUser(name, role) {
  const user = {
    name,
    role,
    permissions: [],
    createdAt: new Date(),
  };
  
  if (role === 'admin') {
    user.permissions = ['read', 'write', 'delete', 'manage'];
  } else if (role === 'editor') {
    user.permissions = ['read', 'write'];
  } else {
    user.permissions = ['read'];
  }
  
  return user;
}
 
// 抽象工厂
class UIFactory {
  createButton() { throw new Error('Not implemented'); }
  createInput() { throw new Error('Not implemented'); }
}
 
class DarkThemeFactory extends UIFactory {
  createButton() {
    return { style: 'dark', text: 'Submit' };
  }
  createInput() {
    return { style: 'dark', placeholder: 'Enter...' };
  }
}
 
class LightThemeFactory extends UIFactory {
  createButton() {
    return { style: 'light', text: 'Submit' };
  }
  createInput() {
    return { style: 'light', placeholder: 'Enter...' };
  }
}

策略模式

class PaymentProcessor {
  constructor(strategy) {
    this.strategy = strategy;
  }
  
  setStrategy(strategy) {
    this.strategy = strategy;
  }
  
  process(amount) {
    return this.strategy.pay(amount);
  }
}
 
const creditCardStrategy = {
  pay(amount) {
    return { method: 'credit_card', amount, transactionId: crypto.randomUUID() };
  }
};
 
const paypalStrategy = {
  pay(amount) {
    return { method: 'paypal', amount, email: 'user@example.com' };
  }
};
 
const cryptoStrategy = {
  pay(amount) {
    return { method: 'crypto', amount, wallet: '0x...' };
  }
};
 
// 使用
const processor = new PaymentProcessor(creditCardStrategy);
processor.process(100);
 
processor.setStrategy(paypalStrategy);
processor.process(200);

JavaScript 测试

Vitest 配置与使用

// vitest.config.js
import { defineConfig } from 'vitest/config';
 
export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      exclude: ['node_modules/', 'dist/']
    },
    testTimeout: 10000,
    hookTimeout: 10000
  }
});
 
// example.test.js
import { describe, it, expect, vi, beforeEach } from 'vitest';
 
describe('Math Utils', () => {
  it('should add two numbers', () => {
    expect(1 + 2).toBe(3);
  });
  
  it('should handle async operations', async () => {
    const result = await Promise.resolve(42);
    expect(result).toBe(42);
  });
});
 
describe('API Client', () => {
  const mockFetch = vi.fn();
  
  beforeEach(() => {
    mockFetch.mockReset();
  });
  
  it('should fetch data', async () => {
    mockFetch.mockResolvedValue({ 
      ok: true, 
      json: async () => ({ data: 'test' }) 
    });
    
    const response = await mockFetch('https://api.example.com');
    const data = await response.json();
    
    expect(data).toEqual({ data: 'test' });
  });
});

测试覆盖率

# 运行测试并生成覆盖率
npx vitest run --coverage
 
# 查看 HTML 报告
npx vitest --coverage --coverage.reporter=html

Mock 函数

// 创建 mock
const mockFn = vi.fn();
 
// 设置实现
mockFn.mockImplementation((x) => x * 2);
 
// 链式调用
mockFn.mockReturnValueOnce(1).mockReturnValueOnce(2).mockReturnValue(3);
 
// 模拟模块
vi.mock('./utils', () => ({
  formatDate: vi.fn((date) => '2024-01-01'),
  parseJSON: vi.fn((str) => JSON.parse(str))
}));
 
// 模拟定时器
vi.useFakeTimers();
 
setTimeout(() => {
  console.log('Delayed');
}, 1000);
 
vi.runAllTimers(); // 立即执行
 
vi.useRealTimers();

JavaScript 性能优化

防抖与节流

// 防抖
function debounce(func, wait) {
  let timeoutId;
  
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}
 
// 节流
function throttle(func, limit) {
  let inThrottle;
  
  return function(...args) {
    if (!inThrottle) {
      func.apply(this, args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}
 
// 使用
const handleInput = debounce((e) => {
  console.log('Search:', e.target.value);
}, 300);
 
const handleScroll = throttle(() => {
  console.log('Scrolled:', window.scrollY);
}, 100);

虚拟列表

class VirtualList {
  constructor(container, items, itemHeight, renderItem) {
    this.container = container;
    this.items = items;
    this.itemHeight = itemHeight;
    this.renderItem = renderItem;
    
    this.visibleCount = Math.ceil(container.clientHeight / itemHeight);
    this.scrollTop = 0;
    
    container.addEventListener('scroll', () => this.onScroll());
    this.render();
  }
  
  onScroll() {
    this.scrollTop = this.container.scrollTop;
    this.render();
  }
  
  render() {
    const startIndex = Math.floor(this.scrollTop / this.itemHeight);
    const endIndex = Math.min(
      startIndex + this.visibleCount + 2,
      this.items.length
    );
    
    const totalHeight = this.items.length * this.itemHeight;
    const offsetY = startIndex * this.itemHeight;
    
    this.container.innerHTML = `
      <div style="height: ${totalHeight}px; position: relative;">
        ${this.items.slice(startIndex, endIndex).map((item, i) => `
          <div style="position: absolute; top: ${offsetY + i * this.itemHeight}px; height: ${this.itemHeight}px;">
            ${this.renderItem(item)}
          </div>
        `).join('')}
      </div>
    `;
  }
}

内存泄漏检测

// 检测全局变量泄漏
function detectLeaks() {
  const initialKeys = Object.keys(window);
  
  return {
    check: () => {
      const currentKeys = Object.keys(window);
      const leaked = currentKeys.filter(k => !initialKeys.includes(k));
      if (leaked.length > 0) {
        console.warn('Potential memory leaks:', leaked);
      }
      return leaked;
    }
  };
}
 
// 使用 WeakMap 避免泄漏
const cache = new WeakMap();
 
function processData(obj) {
  if (cache.has(obj)) {
    return cache.get(obj);
  }
  
  const result = heavyComputation(obj);
  cache.set(obj, result);
  return result;
}
 
// 清理事件监听器
class Component {
  #handler = () => this.onClick();
  
  mount() {
    document.addEventListener('click', this.#handler);
  }
  
  unmount() {
    document.removeEventListener('click', this.#handler);
  }
}

JavaScript 工具链

Vite 配置

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
 
export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  },
  build: {
    target: 'esnext',
    minify: 'terser',
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          utils: ['lodash', 'moment']
        }
      }
    }
  },
  optimizeDeps: {
    include: ['react', 'react-dom']
  }
});

Webpack 配置

// webpack.config.js
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    clean: true,
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react']
          }
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        type: 'asset/resource'
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components')
    }
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      minify: true
    }),
    new DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    })
  ],
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};

ESLint 配置

// .eslintrc.js
module.exports = {
  parserOptions: {
    ecmaVersion: 2022,
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true
    }
  },
  env: {
    browser: true,
    node: true,
    es2022: true
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended'
  ],
  plugins: ['react', '@typescript-eslint'],
  rules: {
    'no-console': 'warn',
    'no-unused-vars': 'warn',
    'prefer-const': 'error',
    'react/prop-types': 'off'
  },
  settings: {
    react: {
      version: 'detect'
    }
  }
};

SUCCESS

JavaScript 作为 Web 开发的基石语言,在 2026 年持续演进。从 ESM 模块系统到现代化的异步编程模式,从浏览器 API 到 Node.js 生态,JavaScript 为全栈开发提供了统一的语言基础。配合 TypeScript 的类型系统,JavaScript 已成为 AI 辅助编程时代最具生产力的语言之一。


JavaScript 高级主题

装饰器提案(Stage 3)

// 装饰器是一种特殊的声明,可以修改类的行为
 
// 基本装饰器
function logged(target, name, descriptor) {
  const original = descriptor.value;
  
  descriptor.value = function(...args) {
    console.log(`Calling ${name} with`, args);
    const result = original.apply(this, args);
    console.log(`Result:`, result);
    return result;
  };
  
  return descriptor;
}
 
class Calculator {
  @logged
  add(a, b) {
    return a + b;
  }
  
  @logged
  multiply(a, b) {
    return a * b;
  }
}
 
const calc = new Calculator();
calc.add(2, 3); // 打印日志并返回结果
 
// 类装饰器
function sealed(constructor) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}
 
@sealed
class Person {
  constructor(name) {
    this.name = name;
  }
}
 
// 装饰器工厂
function prefix(prefix) {
  return function(target, name, descriptor) {
    const original = descriptor.value;
    
    descriptor.value = function(...args) {
      const result = original.apply(this, args);
      return `${prefix}: ${result}`;
    };
    
    return descriptor;
  };
}
 
class Formatter {
  @prefix('Result')
  format(value) {
    return value.toUpperCase();
  }
}
 
// 参数装饰器
function validate(target, name, descriptor) {
  const original = descriptor.value;
  
  descriptor.value = function(...args) {
    if (args.some(arg => arg === undefined)) {
      throw new Error('Arguments cannot be undefined');
    }
    return original.apply(this, args);
  };
  
  return descriptor;
}
 
class Service {
  @validate
  process(data) {
    return data;
  }
}

私有字段与封装

class BankAccount {
  // 真正的私有字段
  #balance = 0;
  #transactionHistory = [];
  
  constructor(initialBalance = 0) {
    this.#balance = initialBalance;
  }
  
  // 公开的 getter
  get balance() {
    return this.#balance;
  }
  
  get transactionCount() {
    return this.#transactionHistory.length;
  }
  
  deposit(amount) {
    if (amount <= 0) {
      throw new Error('Deposit amount must be positive');
    }
    this.#balance += amount;
    this.#recordTransaction('deposit', amount);
    return this;
  }
  
  withdraw(amount) {
    if (amount <= 0) {
      throw new Error('Withdrawal amount must be positive');
    }
    if (amount > this.#balance) {
      throw new Error('Insufficient funds');
    }
    this.#balance -= amount;
    this.#recordTransaction('withdrawal', amount);
    return this;
  }
  
  // 私有方法
  #recordTransaction(type, amount) {
    this.#transactionHistory.push({
      type,
      amount,
      timestamp: new Date()
    });
  }
  
  // 私有 getter
  get #lastTransaction() {
    return this.#transactionHistory.at(-1);
  }
  
  printLastTransaction() {
    console.log('Last transaction:', this.#lastTransaction);
  }
}
 
const account = new BankAccount(1000);
account.deposit(500);
account.withdraw(200);
console.log(account.balance); // 1300
account.printLastTransaction();

Symbol 与 Symbol.for

// Symbol 创建唯一标识符
const id = Symbol('id');
const user = {
  [id]: 1,
  name: 'Alice'
};
 
console.log(user[id]); // 1
 
// Symbol.for 在全局注册表中查找或创建
const sym1 = Symbol.for('app.key');
const sym2 = Symbol.for('app.key');
 
console.log(sym1 === sym2); // true
console.log(Symbol.keyFor(sym1)); // 'app.key'
 
// 常用内置 Symbol
const iterable = {
  [Symbol.iterator]() {
    let step = 0;
    return {
      next() {
        step++;
        return step <= 3 
          ? { value: step, done: false }
          : { done: true };
      }
    };
  }
};
 
for (const v of iterable) {
  console.log(v); // 1, 2, 3
}
 
// Symbol.hasInstance
class EvenNumbers {
  static [Symbol.hasInstance](obj) {
    return Number.isInteger(obj) && obj % 2 === 0;
  }
}
 
console.log(2 instanceof EvenNumbers); // true
console.log(3 instanceof EvenNumbers); // false
 
// Symbol.toStringTag
class Dog {
  get [Symbol.toStringTag]() {
    return 'Dog';
  }
}
 
const dog = new Dog();
console.log(dog.toString()); // '[object Dog]'

代理与元编程

// Proxy 用于自定义基本操作
const handler = {
  get(target, prop, receiver) {
    console.log(`Getting ${prop}`);
    return Reflect.get(target, prop, receiver);
  },
  
  set(target, prop, value, receiver) {
    console.log(`Setting ${prop} = ${value}`);
    return Reflect.set(target, prop, value, receiver);
  },
  
  has(target, prop) {
    console.log(`Checking if ${prop} exists`);
    return Reflect.has(target, prop);
  },
  
  deleteProperty(target, prop) {
    console.log(`Deleting ${prop}`);
    return Reflect.deleteProperty(target, prop);
  }
};
 
const proxy = new Proxy({ name: 'Alice' }, handler);
proxy.name; // 触发 get
proxy.name = 'Bob'; // 触发 set
 
// 验证器示例
const validator = {
  set(target, prop, value) {
    if (prop === 'age') {
      if (typeof value !== 'number') {
        throw new TypeError('Age must be a number');
      }
      if (value < 0 || value > 150) {
        throw new RangeError('Age must be between 0 and 150');
      }
    }
    
    if (prop === 'email') {
      if (!value.includes('@')) {
        throw new Error('Invalid email format');
      }
    }
    
    target[prop] = value;
    return true;
  }
};
 
const person = new Proxy({}, validator);
person.age = 30; // OK
person.email = 'alice@example.com'; // OK
// person.age = 'thirty'; // TypeError
// person.email = 'invalid'; // Error
 
// Reactive 数据绑定
function reactive(obj, onChange) {
  return new Proxy(obj, {
    set(target, prop, value) {
      const oldValue = target[prop];
      target[prop] = value;
      onChange(prop, value, oldValue);
      return true;
    }
  });
}
 
const state = reactive({ count: 0, text: '' }, (prop, value) => {
  console.log(`${prop} changed to ${value}`);
});
 
state.count = 1; // 输出: count changed to 1
state.text = 'Hello'; // 输出: text changed to Hello

迭代器与生成器

// 自定义迭代器
class FibonacciSequence {
  constructor(limit) {
    this.limit = limit;
    this.current = 0;
    this.next = 1;
  }
  
  [Symbol.iterator]() {
    return this;
  }
  
  next() {
    if (this.current > this.limit) {
      return { done: true };
    }
    
    const value = this.current;
    this.current = this.next;
    this.next = value + this.next;
    
    return { value, done: false };
  }
}
 
const fib = new FibonacciSequence(100);
for (const num of fib) {
  console.log(num); // 0, 1, 1, 2, 3, 5, 8, ...
}
 
// 生成器函数
function* numberGenerator() {
  yield 1;
  yield 2;
  yield 3;
}
 
const gen = numberGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().done); // true
 
// 无限生成器
function* infiniteSequence() {
  let i = 0;
  while (true) {
    yield i++;
  }
}
 
function* fibonacciGenerator() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}
 
// 生成器组合
function* filter(iterable, predicate) {
  for (const item of iterable) {
    if (predicate(item)) {
      yield item;
    }
  }
}
 
function* map(iterable, transform) {
  for (const item of iterable) {
    yield transform(item);
  }
}
 
const numbers = [1, 2, 3, 4, 5, 6];
const evens = filter(numbers, n => n % 2 === 0);
const doubled = map(evens, n => n * 2);
 
console.log([...doubled]); // [4, 8, 12]

尾递归优化

// 尾递归函数(某些引擎支持 TCO)
'use strict';
 
function factorial(n, accumulator = 1) {
  if (n <= 1) {
    return accumulator;
  }
  return factorial(n - 1, n * accumulator); // 尾调用
}
 
// trampoline 模式处理尾递归
function trampoline(fn) {
  return function(...args) {
    let result = fn(...args);
    while (typeof result === 'function') {
      result = result();
    }
    return result;
  };
}
 
const factorialTrampoline = trampoline(function factorial(n, acc = 1) {
  if (n <= 1) return acc;
  return () => factorial(n - 1, n * acc);
});
 
console.log(factorialTrampoline(100000)); // 不会栈溢出

WeakRef 与 FinalizationRegistry

// WeakRef 持有对象的弱引用
let obj = { name: 'Alice' };
const weakRef = new WeakRef(obj);
 
console.log(weakRef.deref()?.name); // 'Alice'
 
obj = null; // 清除强引用
 
// 垃圾回收后,deref() 返回 undefined
setTimeout(() => {
  console.log(weakRef.deref()); // undefined
}, 100);
 
// FinalizationRegistry 监听对象被垃圾回收
const registry = new FinalizationRegistry((heldValue) => {
  console.log(`Object with ${heldValue} was garbage collected`);
});
 
let user = { name: 'Bob' };
registry.register(user, user.name);
 
user = null; // 稍后会被垃圾回收
 
// 缓存示例
const cache = new Map();
const cacheRef = new FinalizationRegistry(() => {
  // 清理过期的缓存
  const now = Date.now();
  for (const [key, { expiry }] of cache) {
    if (expiry < now) {
      cache.delete(key);
    }
  }
});
 
function getCached(key, computeFn, ttl = 60000) {
  const cached = cache.get(key);
  if (cached && cached.expiry > Date.now()) {
    return cached.value;
  }
  
  const value = computeFn();
  cache.set(key, {
    value,
    expiry: Date.now() + ttl
  });
  
  cacheRef.register(value, key);
  return value;
}

JavaScript 设计模式

单例模式

const Singleton = (function() {
  let instance = null;
  
  function createInstance() {
    const obj = new Object('I am the singleton');
    return obj;
  }
  
  return {
    getInstance() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();
 
// ES6 类版本
class SingletonClass {
  constructor() {
    if (SingletonClass.instance) {
      return SingletonClass.instance;
    }
    SingletonClass.instance = this;
    this.data = {};
  }
  
  set(key, value) {
    this.data[key] = value;
  }
  
  get(key) {
    return this.data[key];
  }
}
 
// 闭包版本
function SingletonFn() {
  const instance = {
    data: {},
    set(key, value) {
      this.data[key] = value;
    },
    get(key) {
      return this.data[key];
    }
  };
  
  return function() {
    return instance;
  };
}

工厂模式

// 简单工厂
class User {
  constructor(name, type) {
    this.name = name;
    this.type = type;
  }
  
  greet() {
    console.log(`Hi, I am ${this.name}`);
  }
}
 
class Admin extends User {
  greet() {
    console.log(`Admin ${this.name} at your service`);
  }
}
 
class Guest extends User {
  greet() {
    console.log(`Welcome, I am ${this.name}`);
  }
}
 
function UserFactory() {
  return {
    create(type, name) {
      switch (type) {
        case 'admin':
          return new Admin(name, type);
        case 'guest':
          return new Guest(name, type);
        default:
          return new User(name, type);
      }
    }
  };
}
 
const factory = UserFactory();
const admin = factory.create('admin', 'Alice');
const guest = factory.create('guest', 'Bob');

观察者模式

class EventEmitter {
  constructor() {
    this.events = {};
  }
  
  on(event, listener) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(listener);
    return () => this.off(event, listener);
  }
  
  once(event, listener) {
    const wrapper = (...args) => {
      listener(...args);
      this.off(event, wrapper);
    };
    return this.on(event, wrapper);
  }
  
  off(event, listener) {
    if (!this.events[event]) return;
    this.events[event] = this.events[event].filter(l => l !== listener);
  }
  
  emit(event, ...args) {
    if (!this.events[event]) return;
    this.events[event].forEach(listener => listener(...args));
  }
}
 
const emitter = new EventEmitter();
 
emitter.on('message', (msg) => console.log('Handler 1:', msg));
const off = emitter.on('message', (msg) => console.log('Handler 2:', msg));
 
emitter.emit('message', 'Hello!'); // 两个处理器都会执行
 
off(); // 移除第二个处理器
emitter.emit('message', 'World!'); // 只有第一个处理器执行

中介者模式

class ChatRoom {
  constructor() {
    this.users = new Map();
  }
  
  register(user) {
    this.users.set(user.id, user);
    user.room = this;
    this.broadcast('system', `${user.name} has joined`);
  }
  
  unregister(user) {
    this.users.delete(user.id);
    this.broadcast('system', `${user.name} has left`);
  }
  
  broadcast(sender, message) {
    this.users.forEach(user => {
      if (user !== sender) {
        user.receive(sender, message);
      }
    });
  }
  
  direct(sender, receiverId, message) {
    const receiver = this.users.get(receiverId);
    if (receiver) {
      receiver.receive(sender, message, true);
    }
  }
}
 
class User {
  constructor(id, name) {
    this.id = id;
    this.name = name;
    this.room = null;
  }
  
  receive(sender, message, isDirect = false) {
    const prefix = isDirect ? '(DM)' : '';
    console.log(`${prefix}${sender.name} -> ${this.name}: ${message}`);
  }
  
  send(message) {
    this.room.broadcast(this, message);
  }
  
  sendTo(receiverId, message) {
    this.room.direct(this, receiverId, message);
  }
}
 
const room = new ChatRoom();
const alice = new User(1, 'Alice');
const bob = new User(2, 'Bob');
 
room.register(alice);
room.register(bob);
 
alice.send('Hello everyone!'); // 广播给 Bob
alice.sendTo(2, 'Hi Bob!'); // 只发给 Bob

参考资料

资源链接
MDN Web Docshttps://developer.mozilla.org/
JavaScript.infohttps://javascript.info/
TC39 Proposalshttps://github.com/tc39/proposals
Can I Usehttps://caniuse.com/
Node.js Documentationhttps://nodejs.org/docs/
V8 JavaScript Enginehttps://v8.dev/
JavaScript Weeklyhttps://javascriptweekly.com/

TIP

JavaScript 的生态系统极其丰富,合理利用现代 ES2024+ 特性和工具链,可以构建出高性能、可靠的应用程序。