前言:为什么你还在用老掉牙的API?
作为一名前端开发者,你是否还在用着document.getElementById
这种上古时代的API?是否还在为复杂的DOM操作而头疼?今天,我将带你揭秘20个现代JavaScript API的奇迹淫巧,每个API都配有3个实用示例,让你的开发效率提升300%!
1. Intersection Observer API - 懒加载的神器
示例1:图片懒加载
javascript
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
示例2:无限滚动
javascript
const loadMoreObserver = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
loadMoreContent();
}
});
loadMoreObserver.observe(document.querySelector('#load-more-trigger'));
示例3:元素进入视口动画
javascript
const animateOnScroll = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in');
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.animate-on-scroll').forEach(el => {
animateOnScroll.observe(el);
});
2. Fetch API - 告别XMLHttpRequest
示例1:基本GET请求
javascript
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
示例2:POST请求带JSON数据
javascript
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'John Doe',
email: 'john@example.com'
})
})
.then(response => response.json())
.then(data => console.log('Success:', data));
示例3:带超时和取消的请求
javascript
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
fetch('https://api.example.com/slow', {
signal: controller.signal
})
.then(response => response.json())
.finally(() => clearTimeout(timeoutId));
3. LocalStorage API - 客户端存储利器
示例1:存储用户设置
javascript
// 保存设置
const saveSettings = (settings) => {
localStorage.setItem('userSettings', JSON.stringify(settings));
};
// 读取设置
const loadSettings = () => {
const settings = localStorage.getItem('userSettings');
return settings ? JSON.parse(settings) : {};
};
示例2:购物车持久化
javascript
class ShoppingCart {
constructor() {
this.items = this.loadCart();
}
loadCart() {
return JSON.parse(localStorage.getItem('cart')) || [];
}
saveCart() {
localStorage.setItem('cart', JSON.stringify(this.items));
}
addItem(item) {
this.items.push(item);
this.saveCart();
}
}
示例3:用户行为追踪
javascript
const trackUserAction = (action, data) => {
const userActions = JSON.parse(localStorage.getItem('userActions')) || [];
userActions.push({ action, data, timestamp: Date.now() });
localStorage.setItem('userActions', JSON.stringify(userActions));
};
4. Service Worker API - PWA的核心
示例1:注册Service Worker
javascript
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('SW registered: ', registration);
})
.catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
}
示例2:缓存策略
javascript
// sw.js
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) return response;
return fetch(event.request);
})
);
});
示例3:后台同步
javascript
// 注册后台同步
navigator.serviceWorker.ready.then(registration => {
return registration.sync.register('sync-data');
});
// Service Worker中处理同步
self.addEventListener('sync', event => {
if (event.tag === 'sync-data') {
event.waitUntil(syncData());
}
});
5. Web Workers API - 多线程编程
示例1:创建Web Worker
javascript
// 主线程
const worker = new Worker('worker.js');
worker.postMessage('开始计算');
worker.onmessage = e => console.log('结果:', e.data);
// worker.js
self.onmessage = e => {
const result = heavyCalculation();
self.postMessage(result);
};
示例2:图像处理
javascript
// 使用Worker处理图像
function processImageInWorker(imageData) {
return new Promise((resolve) => {
const worker = new Worker('/js/image-processor.js');
worker.postMessage(imageData);
worker.onmessage = e => resolve(e.data);
});
}
示例3:实时数据分析
javascript
// 实时数据处理Worker
class DataProcessor extends Worker {
constructor() {
super('/js/data-processor.js');
this.queue = [];
}
process(data) {
this.queue.push(data);
if (this.queue.length === 1) this.processNext();
}
processNext() {
if (this.queue.length > 0) {
this.postMessage(this.queue[0]);
}
}
}
6. WebSocket API - 实时通信的终极武器
示例1:建立WebSocket连接
javascript
const socket = new WebSocket('wss://echo.websocket.org');
socket.onopen = () => {
console.log('连接已建立');
socket.send('Hello Server!');
};
socket.onmessage = (event) => {
console.log('收到消息:', event.data);
};
socket.onclose = () => {
console.log('连接已关闭');
};
示例2:实时聊天应用
javascript
class ChatClient {
constructor(url) {
this.socket = new WebSocket(url);
this.setupEventListeners();
}
setupEventListeners() {
this.socket.onmessage = (event) => {
const message = JSON.parse(event.data);
this.displayMessage(message);
};
this.socket.onerror = (error) => {
console.error('WebSocket错误:', error);
};
}
sendMessage(message) {
if (this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(message));
}
}
}
示例3:心跳检测
javascript
function createWebSocketWithHeartbeat(url) {
const ws = new WebSocket(url);
let heartbeatInterval;
ws.onopen = () => {
console.log('连接成功,开始心跳检测');
heartbeatInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'heartbeat' }));
}
}, 30000);
};
ws.onclose = () => {
clearInterval(heartbeatInterval);
console.log('连接关闭,停止心跳');
};
return ws;
}
7. Geolocation API - 地理位置追踪
示例1:获取当前位置
javascript
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition(
(position) => {
console.log('纬度:', position.coords.latitude);
console.log('经度:', position.coords.longitude);
console.log('精度:', position.coords.accuracy);
},
(error) => {
console.error('获取位置失败:', error.message);
},
{ enableHighAccuracy: true, timeout: 10000 }
);
}
示例2:持续位置追踪
javascript
let watchId;
function startTracking() {
watchId = navigator.geolocation.watchPosition(
(position) => {
updateMap(position.coords);
},
(error) => {
console.error('追踪错误:', error);
},
{ enableHighAccuracy: true }
);
}
function stopTracking() {
if (watchId) {
navigator.geolocation.clearWatch(watchId);
}
}
示例3:距离计算
javascript
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // 地球半径(km)
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
// 使用示例
navigator.geolocation.getCurrentPosition((pos) => {
const distance = calculateDistance(
pos.coords.latitude, pos.coords.longitude,
31.2304, 121.4737 // 上海坐标
);
console.log(`距离上海: ${distance.toFixed(2)}km`);
});
8. Notification API - 桌面通知
示例1:请求通知权限
javascript
async function requestNotificationPermission() {
if ('Notification' in window) {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
console.log('通知权限已授予');
return true;
} else {
console.log('通知权限被拒绝');
return false;
}
}
return false;
}
示例2:发送通知
javascript
function showNotification(title, options = {}) {
if ('Notification' in window && Notification.permission === 'granted') {
const notification = new Notification(title, {
body: options.body || '',
icon: options.icon || '/icon.png',
tag: options.tag || 'default',
data: options.data || {}
});
notification.onclick = () => {
window.focus();
notification.close();
};
return notification;
}
}
// 使用示例
showNotification('新消息', {
body: '您收到了一条新消息',
icon: '/message-icon.png'
});
示例3:定时提醒
javascript
class ReminderSystem {
constructor() {
this.reminders = new Map();
}
setReminder(time, message, options = {}) {
const now = Date.now();
const delay = time - now;
if (delay > 0) {
const timeoutId = setTimeout(() => {
this.showReminder(message, options);
this.reminders.delete(timeoutId);
}, delay);
this.reminders.set(timeoutId, { time, message });
return timeoutId;
}
}
showReminder(message, options) {
if (Notification.permission === 'granted') {
new Notification('提醒', {
body: message,
icon: options.icon,
requireInteraction: true
});
}
}
}
9. Clipboard API - 剪贴板操作
示例1:复制文本到剪贴板
javascript
async function copyToClipboard(text) {
try {
await navigator.clipboard.writeText(text);
console.log('文本已复制到剪贴板');
return true;
} catch (err) {
console.error('复制失败:', err);
// 备用方案
const textArea = document.createElement('textarea');
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
return false;
}
}
示例2:读取剪贴板内容
javascript
async function readClipboard() {
try {
const text = await navigator.clipboard.readText();
console.log('剪贴板内容:', text);
return text;
} catch (err) {
console.error('读取剪贴板失败:', err);
return null;
}
}
示例3:复制富文本内容
javascript
async function copyRichText(html) {
try {
const blob = new Blob([html], { type: 'text/html' });
const clipboardItem = new ClipboardItem({ 'text/html': blob });
await navigator.clipboard.write([clipboardItem]);
console.log('富文本已复制');
} catch (err) {
console.error('复制富文本失败:', err);
}
}
10. File API - 现代文件处理
示例1:文件选择与读取
javascript
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.txt,.pdf,.jpg,.png';
fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0];
if (file) {
const content = await readFileContent(file);
console.log('文件内容:', content);
}
});
function readFileContent(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => resolve(e.target.result);
reader.onerror = (e) => reject(e.target.error);
if (file.type.startsWith('text/')) {
reader.readAsText(file);
} else {
reader.readAsDataURL(file);
}
});
}
示例2:拖放文件上传
javascript
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
const files = Array.from(e.dataTransfer.files);
handleDroppedFiles(files);
});
async function handleDroppedFiles(files) {
for (const file of files) {
if (file.type.startsWith('image/')) {
const imageUrl = URL.createObjectURL(file);
displayImage(imageUrl);
}
}
}
示例3:大文件分片上传
javascript
async function uploadLargeFile(file, chunkSize = 1024 * 1024) {
const totalChunks = Math.ceil(file.size / chunkSize);
const fileId = Date.now().toString();
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
const start = chunkIndex * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('file', chunk);
formData.append('chunkIndex', chunkIndex);
formData.append('totalChunks', totalChunks);
formData.append('fileId', fileId);
formData.append('fileName', file.name);
await fetch('/upload-chunk', {
method: 'POST',
body: formData
});
updateProgress((chunkIndex + 1) / totalChunks * 100);
}
// 通知服务器合并文件
await fetch('/merge-file', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileId, fileName: file.name })
});
}
11. IndexedDB API - 客户端数据库的终极解决方案
示例1:创建数据库和对象存储
javascript
const openDB = (name, version) => {
return new Promise((resolve, reject) => {
const request = indexedDB.open(name, version);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 创建对象存储
if (!db.objectStoreNames.contains('users')) {
const store = db.createObjectStore('users', { keyPath: 'id' });
store.createIndex('email', 'email', { unique: true });
}
if (!db.objectStoreNames.contains('products')) {
db.createObjectStore('products', { keyPath: 'id', autoIncrement: true });
}
};
});
};
// 使用示例
const db = await openDB('MyApp', 1);
示例2:CRUD操作
javascript
class IDBManager {
constructor(dbName, version) {
this.db = null;
this.initialize(dbName, version);
}
async initialize(dbName, version) {
this.db = await openDB(dbName, version);
}
async add(storeName, data) {
const transaction = this.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
return store.add(data);
}
async get(storeName, key) {
const transaction = this.db.transaction([storeName], 'readonly');
const store = transaction.objectStore(storeName);
return store.get(key);
}
async getAll(storeName) {
const transaction = this.db.transaction([storeName], 'readonly');
const store = transaction.objectStore(storeName);
return store.getAll();
}
async update(storeName, data) {
const transaction = this.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
return store.put(data);
}
async delete(storeName, key) {
const transaction = this.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
return store.delete(key);
}
}
示例3:复杂查询和事务
javascript
async function complexQuery() {
const db = await openDB('Ecommerce', 2);
const transaction = db.transaction(['users', 'orders'], 'readonly');
// 使用索引查询
const userStore = transaction.objectStore('users');
const emailIndex = userStore.index('email');
const user = await emailIndex.get('user@example.com');
// 获取用户的订单
const orderStore = transaction.objectStore('orders');
const userOrders = await orderStore.getAll(IDBKeyRange.only(user.id));
// 使用游标遍历
const cursorRequest = orderStore.openCursor();
const expensiveOrders = [];
cursorRequest.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
if (cursor.value.total > 1000) {
expensiveOrders.push(cursor.value);
}
cursor.continue();
}
};
return { user, orders: userOrders, expensiveOrders };
}
12. Canvas API - 高性能图形绘制
示例1:基础绘图
javascript
class CanvasRenderer {
constructor(canvasId) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
this.setupCanvas();
}
setupCanvas() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
drawCircle(x, y, radius, color) {
this.ctx.beginPath();
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
this.ctx.fillStyle = color;
this.ctx.fill();
this.ctx.closePath();
}
drawText(text, x, y, options = {}) {
this.ctx.font = options.font || '16px Arial';
this.ctx.fillStyle = options.color || '#000';
this.ctx.textAlign = options.align || 'left';
this.ctx.fillText(text, x, y);
}
clear() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
示例2:图像处理和滤镜
javascript
class ImageProcessor {
constructor(canvas) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
}
applyGrayscale() {
const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
data[i] = avg; // R
data[i + 1] = avg; // G
data[i + 2] = avg; // B
}
this.ctx.putImageData(imageData, 0, 0);
}
applySepia() {
const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
data[i] = Math.min(255, (r * 0.393) + (g * 0.769) + (b * 0.189));
data[i + 1] = Math.min(255, (r * 0.349) + (g * 0.686) + (b * 0.168));
data[i + 2] = Math.min(255, (r * 0.272) + (g * 0.534) + (b * 0.131));
}
this.ctx.putImageData(imageData, 0, 0);
}
}
示例3:动画和游戏开发
javascript
class GameEngine {
constructor(canvasId) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
this.objects = [];
this.running = false;
this.lastTime = 0;
}
addObject(obj) {
this.objects.push(obj);
}
start() {
this.running = true;
requestAnimationFrame(this.loop.bind(this));
}
stop() {
this.running = false;
}
loop(timestamp) {
const deltaTime = timestamp - this.lastTime;
this.lastTime = timestamp;
this.update(deltaTime);
this.render();
if (this.running) {
requestAnimationFrame(this.loop.bind(this));
}
}
update(deltaTime) {
this.objects.forEach(obj => {
if (obj.update) obj.update(deltaTime);
});
}
render() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.objects.forEach(obj => {
if (obj.render) obj.render(this.ctx);
});
}
}
13. Web Audio API - 专业音频处理
示例1:音频播放和控制
javascript
class AudioPlayer {
constructor() {
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.audioBuffer = null;
this.source = null;
}
async loadAudio(url) {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
this.audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
}
play() {
if (this.audioBuffer) {
this.source = this.audioContext.createBufferSource();
this.source.buffer = this.audioBuffer;
// 添加音量控制
const gainNode = this.audioContext.createGain();
gainNode.gain.value = 0.5;
this.source.connect(gainNode);
gainNode.connect(this.audioContext.destination);
this.source.start();
}
}
stop() {
if (this.source) {
this.source.stop();
}
}
}
示例2:音频可视化
javascript
class AudioVisualizer {
constructor(canvas, audioElement) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.audioContext = new AudioContext();
this.analyser = this.audioContext.createAnalyser();
this.source = this.audioContext.createMediaElementSource(audioElement);
this.source.connect(this.analyser);
this.analyser.connect(this.audioContext.destination);
this.analyser.fftSize = 256;
this.bufferLength = this.analyser.frequencyBinCount;
this.dataArray = new Uint8Array(this.bufferLength);
this.setupCanvas();
}
setupCanvas() {
this.canvas.width = window.innerWidth;
this.canvas.height = 200;
}
draw() {
requestAnimationFrame(this.draw.bind(this));
this.analyser.getByteFrequencyData(this.dataArray);
this.ctx.fillStyle = 'rgb(0, 0, 0)';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
const barWidth = (this.canvas.width / this.bufferLength) * 2.5;
let barHeight;
let x = 0;
for (let i = 0; i < this.bufferLength; i++) {
barHeight = this.dataArray[i] / 2;
this.ctx.fillStyle = `rgb(${barHeight + 100}, 50, 50)`;
this.ctx.fillRect(x, this.canvas.height - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
}
示例3:音频效果处理
javascript
class AudioEffects {
constructor(audioContext) {
this.audioContext = audioContext;
}
createReverb() {
const convolver = this.audioContext.createConvolver();
// 创建脉冲响应(模拟混响)
const bufferSize = this.audioContext.sampleRate;
const buffer = this.audioContext.createBuffer(2, bufferSize, this.audioContext.sampleRate);
for (let channel = 0; channel < 2; channel++) {
const data = buffer.getChannelData(channel);
for (let i = 0; i < bufferSize; i++) {
data[i] = Math.random() * 2 - 1;
}
}
convolver.buffer = buffer;
return convolver;
}
createDelay(delayTime = 0.5, feedback = 0.3) {
const delay = this.audioContext.createDelay();
const feedbackGain = this.audioContext.createGain();
delay.delayTime.value = delayTime;
feedbackGain.gain.value = feedback;
delay.connect(feedbackGain);
feedbackGain.connect(delay);
return { delay, feedbackGain };
}
createFilter(type = 'lowpass', frequency = 1000) {
const filter = this.audioContext.createBiquadFilter();
filter.type = type;
filter.frequency.value = frequency;
return filter;
}
}
14. WebRTC API - 实时音视频通信
示例1:建立视频通话
javascript
class VideoCall {
constructor() {
this.localStream = null;
this.peerConnection = null;
this.configuration = {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:stun1.l.google.com:19302' }
]
};
}
async startLocalVideo() {
try {
this.localStream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
const videoElement = document.getElementById('localVideo');
videoElement.srcObject = this.localStream;
} catch (error) {
console.error('获取媒体设备失败:', error);
}
}
createPeerConnection() {
this.peerConnection = new RTCPeerConnection(this.configuration);
// 添加本地流
this.localStream.getTracks().forEach(track => {
this.peerConnection.addTrack(track, this.localStream);
});
// 处理远程流
this.peerConnection.ontrack = (event) => {
const remoteVideo = document.getElementById('remoteVideo');
remoteVideo.srcObject = event.streams[0];
};
// ICE候选处理
this.peerConnection.onicecandidate = (event) => {
if (event.candidate) {
// 发送候选到对等端
this.sendSignal({ type: 'candidate', candidate: event.candidate });
}
};
}
}
示例2:屏幕共享
javascript
async function startScreenShare() {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: {
cursor: 'always',
displaySurface: 'window'
},
audio: true
});
const videoElement = document.createElement('video');
videoElement.srcObject = stream;
videoElement.autoplay = true;
document.body.appendChild(videoElement);
// 监听停止共享
const videoTrack = stream.getVideoTracks()[0];
videoTrack.onended = () => {
console.log('屏幕共享已停止');
videoElement.remove();
};
} catch (error) {
console.error('屏幕共享失败:', error);
}
}
示例3:数据通道通信
javascript
class DataChannelManager {
constructor(peerConnection) {
this.peerConnection = peerConnection;
this.dataChannel = null;
this.setupDataChannel();
}
setupDataChannel() {
this.dataChannel = this.peerConnection.createDataChannel('chat');
this.dataChannel.onopen = () => {
console.log('数据通道已建立');
};
this.dataChannel.onmessage = (event) => {
this.handleMessage(JSON.parse(event.data));
};
this.dataChannel.onclose = () => {
console.log('数据通道已关闭');
};
}
sendMessage(message) {
if (this.dataChannel && this.dataChannel.readyState === 'open') {
this.dataChannel.send(JSON.stringify(message));
}
}
handleMessage(message) {
switch (message.type) {
case 'text':
this.displayMessage(message.content);
break;
case 'file':
this.handleFile(message);
break;
case 'command':
this.executeCommand(message);
break;
}
}
}
15. Mutation Observer API - DOM变化监听
示例1:监听元素变化
javascript
class DOMWatcher {
constructor(targetSelector, options = {}) {
this.target = document.querySelector(targetSelector);
this.observer = new MutationObserver(this.handleMutations.bind(this));
this.options = {
childList: true,
attributes: true,
subtree: true,
...options
};
}
start() {
this.observer.observe(this.target, this.options);
}
stop() {
this.observer.disconnect();
}
handleMutations(mutations) {
mutations.forEach(mutation => {
switch (mutation.type) {
case 'childList':
this.handleChildListChange(mutation);
break;
case 'attributes':
this.handleAttributeChange(mutation);
break;
}
});
}
handleChildListChange(mutation) {
console.log('子节点变化:', {
addedNodes: Array.from(mutation.addedNodes),
removedNodes: Array.from(mutation.removedNodes)
});
}
handleAttributeChange(mutation) {
console.log('属性变化:', {
attributeName: mutation.attributeName,
oldValue: mutation.oldValue,
newValue: mutation.target.getAttribute(mutation.attributeName)
});
}
}
示例2:无限滚动检测
javascript
class InfiniteScrollDetector {
constructor(containerSelector, loadMoreCallback) {
this.container = document.querySelector(containerSelector);
this.loadMoreCallback = loadMoreCallback;
this.observer = new MutationObserver(this.checkScroll.bind(this));
this.lastItemCount = 0;
}
start() {
this.observer.observe(this.container, {
childList: true,
subtree: true
});
}
checkScroll() {
const currentItemCount = this.container.children.length;
if (currentItemCount > this.lastItemCount) {
// 新项目添加,检查是否需要加载更多
const lastItem = this.container.lastElementChild;
const lastItemRect = lastItem.getBoundingClientRect();
if (lastItemRect.bottom <= window.innerHeight + 100) {
this.loadMoreCallback();
}
}
this.lastItemCount = currentItemCount;
}
}
示例3:动态内容水合
javascript
class DynamicContentHydrator {
constructor() {
this.observers = new Map();
this.handlers = new Map();
}
watchElement(selector, handler) {
const element = document.querySelector(selector);
if (!element) return;
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
handler(element);
}
});
});
observer.observe(element, { childList: true, subtree: true });
this.observers.set(selector, observer);
this.handlers.set(selector, handler);
}
unwatchElement(selector) {
const observer = this.observers.get(selector);
if (observer) {
observer.disconnect();
this.observers.delete(selector);
this.handlers.delete(selector);
}
}
// 立即执行一次处理
hydrateNow(selector) {
const handler = this.handlers.get(selector);
const element = document.querySelector(selector);
if (handler && element) {
handler(element);
}
}
}
16. Resize Observer API - 响应式布局的终极监听器
示例1:元素尺寸变化监听
javascript
class ResponsiveLayoutManager {
constructor() {
this.observers = new Map();
this.resizeObserver = new ResizeObserver(this.handleResize.bind(this));
}
observeElement(element, callback, options = {}) {
const entry = { element, callback, options };
this.observers.set(element, entry);
this.resizeObserver.observe(element, options);
}
unobserveElement(element) {
this.resizeObserver.unobserve(element);
this.observers.delete(element);
}
handleResize(entries) {
entries.forEach(entry => {
const { target, contentRect, borderBoxSize, contentBoxSize } = entry;
const observerEntry = this.observers.get(target);
if (observerEntry) {
observerEntry.callback({
element: target,
width: contentRect.width,
height: contentRect.height,
borderBoxSize: borderBoxSize?.[0],
contentBoxSize: contentBoxSize?.[0],
timestamp: Date.now()
});
}
});
}
}
// 使用示例
const layoutManager = new ResponsiveLayoutManager();
const container = document.getElementById('responsive-container');
layoutManager.observeElement(container, (sizeInfo) => {
console.log('容器尺寸变化:', sizeInfo);
if (sizeInfo.width < 768) {
container.classList.add('mobile-layout');
} else {
container.classList.remove('mobile-layout');
}
});
示例2:响应式组件适配
javascript
class ResponsiveComponent {
constructor(element) {
this.element = element;
this.breakpoints = {
mobile: 576,
tablet: 768,
desktop: 992,
large: 1200
};
this.setupResizeObserver();
}
setupResizeObserver() {
this.observer = new ResizeObserver(entries => {
const { width } = entries[0].contentRect;
this.updateLayout(width);
});
this.observer.observe(this.element);
}
updateLayout(width) {
let layoutType = 'mobile';
if (width >= this.breakpoints.large) {
layoutType = 'large';
} else if (width >= this.breakpoints.desktop) {
layoutType = 'desktop';
} else if (width >= this.breakpoints.tablet) {
layoutType = 'tablet';
}
this.applyLayoutStyles(layoutType, width);
}
applyLayoutStyles(layoutType, width) {
this.element.setAttribute('data-layout', layoutType);
this.element.style.setProperty('--current-width', `${width}px`);
// 根据布局类型应用不同的样式类
const layoutClasses = ['mobile-layout', 'tablet-layout', 'desktop-layout', 'large-layout'];
this.element.classList.remove(...layoutClasses);
this.element.classList.add(`${layoutType}-layout`);
}
destroy() {
this.observer.disconnect();
}
}
示例3:性能优化的防抖监听
javascript
class DebouncedResizeObserver {
constructor(callback, delay = 100) {
this.callback = callback;
this.delay = delay;
this.timeoutId = null;
this.lastEntries = null;
this.observer = new ResizeObserver(entries => {
this.lastEntries = entries;
this.scheduleCallback();
});
}
observe(element, options) {
this.observer.observe(element, options);
}
unobserve(element) {
this.observer.unobserve(element);
}
disconnect() {
this.observer.disconnect();
this.clearSchedule();
}
scheduleCallback() {
this.clearSchedule();
this.timeoutId = setTimeout(() => {
this.callback(this.lastEntries);
this.lastEntries = null;
}, this.delay);
}
clearSchedule() {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
this.timeoutId = null;
}
}
}
// 使用示例
const debouncedObserver = new DebouncedResizeObserver(entries => {
entries.forEach(entry => {
console.log('防抖后的尺寸变化:', entry.contentRect);
});
}, 150);
debouncedObserver.observe(document.getElementById('main-content'));
17. Performance API - 应用性能监控专家
示例1:性能指标采集
javascript
class PerformanceMonitor {
constructor() {
this.metrics = new Map();
this.observers = [];
}
startMeasure(name) {
if (this.metrics.has(name)) {
console.warn(`测量项 ${name} 已存在`);
return;
}
performance.mark(`${name}-start`);
this.metrics.set(name, {
startTime: performance.now(),
startMark: `${name}-start`
});
}
endMeasure(name) {
const metric = this.metrics.get(name);
if (!metric) {
console.warn(`测量项 ${name} 不存在`);
return null;
}
performance.mark(`${name}-end`);
performance.measure(name, `${name}-start`, `${name}-end`);
const duration = performance.now() - metric.startTime;
const entry = performance.getEntriesByName(name).pop();
this.metrics.delete(name);
this.notifyObservers({ name, duration, entry });
return duration;
}
measureNavigationTiming() {
const navigation = performance.getEntriesByType('navigation')[0];
if (!navigation) return null;
return {
dns: navigation.domainLookupEnd - navigation.domainLookupStart,
tcp: navigation.connectEnd - navigation.connectStart,
request: navigation.responseStart - navigation.requestStart,
response: navigation.responseEnd - navigation.responseStart,
domContentLoaded: navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart,
load: navigation.loadEventEnd - navigation.loadEventStart,
total: navigation.loadEventEnd - navigation.navigationStart
};
}
measureResourceTiming() {
return performance.getEntriesByType('resource').map(resource => ({
name: resource.name,
duration: resource.duration,
transferSize: resource.transferSize,
initiatorType: resource.initiatorType
}));
}
addObserver(callback) {
this.observers.push(callback);
}
notifyObservers(data) {
this.observers.forEach(callback => callback(data));
}
}
示例2:用户体验核心指标监控
javascript
class CoreWebVitals {
constructor() {
this.metrics = {};
this.setupCLS();
this.setupLCP();
this.setupFID();
}
setupCLS() {
let clsValue = 0;
let sessionValue = 0;
let sessionEntries = [];
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) {
sessionValue += entry.value;
sessionEntries.push(entry);
clsValue = sessionValue;
}
}
});
observer.observe({ type: 'layout-shift', buffered: true });
this.metrics.CLS = {
value: () => clsValue,
entries: () => sessionEntries
};
}
setupLCP() {
let lcpValue = 0;
const observer = new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
lcpValue = lastEntry.startTime;
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });
this.metrics.LCP = {
value: () => lcpValue,
entries: () => performance.getEntriesByName('largest-contentful-paint')
};
}
setupFID() {
let fidValue = Infinity;
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
fidValue = Math.min(fidValue, entry.processingStart - entry.startTime);
}
});
observer.observe({ type: 'first-input', buffered: true });
this.metrics.FID = {
value: () => fidValue,
entries: () => performance.getEntriesByName('first-input')
};
}
reportToAnalytics() {
const vitals = {
CLS: this.metrics.CLS.value(),
LCP: this.metrics.LCP.value(),
FID: this.metrics.FID.value(),
timestamp: Date.now()
};
// 发送到分析平台
navigator.sendBeacon('/analytics/vitals', JSON.stringify(vitals));
}
}
示例3:自定义性能标记和测量
javascript
class CustomPerformanceTracker {
constructor() {
this.markers = new Map();
this.measures = new Map();
}
mark(name, detail = {}) {
performance.mark(name);
this.markers.set(name, {
timestamp: performance.now(),
detail
});
return this.markers.get(name);
}
measure(measureName, startMark, endMark, detail = {}) {
performance.measure(measureName, startMark, endMark);
const entries = performance.getEntriesByName(measureName);
const measureEntry = entries[entries.length - 1];
this.measures.set(measureName, {
name: measureName,
duration: measureEntry.duration,
startTime: measureEntry.startTime,
detail,
entries: measureEntry.entries || []
});
return this.measures.get(measureName);
}
measureBetween(measureName, startMarkName, endMarkName, detail = {}) {
const startMark = this.markers.get(startMarkName);
const endMark = this.markers.get(endMarkName);
if (!startMark || !endMark) {
throw new Error('开始或结束标记不存在');
}
return this.measure(measureName, startMarkName, endMarkName, {
...detail,
startDetail: startMark.detail,
endDetail: endMark.detail
});
}
getMeasuresByThreshold(threshold) {
return Array.from(this.measures.values()).filter(
measure => measure.duration >= threshold
);
}
clear() {
performance.clearMarks();
performance.clearMeasures();
this.markers.clear();
this.measures.clear();
}
exportData() {
return {
markers: Array.from(this.markers.entries()),
measures: Array.from(this.measures.entries()),
navigation: performance.getEntriesByType('navigation')[0],
resources: performance.getEntriesByType('resource')
};
}
}
18. Intl API - 国际化处理大师
示例1:多语言格式化
javascript
class InternationalizationService {
constructor(locale = 'zh-CN') {
this.locale = locale;
this.formatters = new Map();
}
setLocale(locale) {
this.locale = locale;
this.formatters.clear(); // 清除缓存的格式化器
}
formatNumber(number, options = {}) {
const key = `number-${JSON.stringify(options)}`;
if (!this.formatters.has(key)) {
this.formatters.set(key, new Intl.NumberFormat(this.locale, options));
}
return this.formatters.get(key).format(number);
}
formatCurrency(amount, currency = 'CNY', options = {}) {
return this.formatNumber(amount, {
style: 'currency',
currency,
...options
});
}
formatDate(date, options = {}) {
const key = `date-${JSON.stringify(options)}`;
if (!this.formatters.has(key)) {
this.formatters.set(key, new Intl.DateTimeFormat(this.locale, options));
}
return this.formatters.get(key).format(date);
}
formatRelativeTime(value, unit, options = {}) {
const key = `relative-${unit}-${JSON.stringify(options)}`;
if (!this.formatters.has(key)) {
this.formatters.set(key, new Intl.RelativeTimeFormat(this.locale, options));
}
return this.formatters.get(key).format(value, unit);
}
formatList(items, options = {}) {
const key = `list-${JSON.stringify(options)}`;
if (!this.formatters.has(key)) {
this.formatters.set(key, new Intl.ListFormat(this.locale, options));
}
return this.formatters.get(key).format(items);
}
// 智能相对时间格式化
formatSmartRelativeTime(timestamp) {
const now = Date.now();
const diff = timestamp - now;
const absDiff = Math.abs(diff);
if (absDiff < 60000) { // 1分钟内
return this.formatRelativeTime(Math.round(diff / 1000), 'second');
} else if (absDiff < 3600000) { // 1小时内
return this.formatRelativeTime(Math.round(diff / 60000), 'minute');
} else if (absDiff < 86400000) { // 1天内
return this.formatRelativeTime(Math.round(diff / 3600000), 'hour');
} else if (absDiff < 2592000000) { // 30天内
return this.formatRelativeTime(Math.round(diff / 86400000), 'day');
} else {
return this.formatDate(new Date(timestamp));
}
}
}
示例2:多语言排序和比较
javascript
class LocaleAwareSorter {
constructor(locale = 'zh-CN', options = {}) {
this.collator = new Intl.Collator(locale, {
sensitivity: 'base',
numeric: true,
...options
});
}
sortStrings(strings, order = 'asc') {
const sorted = [...strings].sort(this.collator.compare);
return order === 'desc' ? sorted.reverse() : sorted;
}
sortObjects(array, key, order = 'asc') {
const sorted = [...array].sort((a, b) =>
this.collator.compare(a[key], b[key])
);
return order === 'desc' ? sorted.reverse() : sorted;
}
searchStrings(strings, query) {
return strings.filter(str =>
this.collator.compare(str, query) === 0
);
}
// 智能搜索(包含部分匹配)
fuzzySearch(strings, query) {
const queryLower = query.toLowerCase();
return strings.filter(str => {
const strLower = str.toLowerCase();
return this.collator.compare(strLower, queryLower) === 0 ||
strLower.includes(queryLower);
});
}
}
// 使用示例
const sorter = new LocaleAwareSorter('zh-CN');
const names = ['张三', '李四', '王五', '赵六'];
console.log(sorter.sortStrings(names)); // ['李四', '王五', '张三', '赵六']
示例3:多语言复数处理
javascript
class PluralizationService {
constructor(locale = 'zh-CN') {
this.pluralRules = new Intl.PluralRules(locale);
this.supportedLocales = ['en', 'zh-CN', 'fr', 'de', 'es', 'ru', 'ja'];
}
getPluralForm(number, locale = this.pluralRules.resolvedOptions().locale) {
return this.pluralRules.select(number);
}
formatWithPlural(number, forms, locale = 'zh-CN') {
const form = this.getPluralForm(number, locale);
if (typeof forms === 'object') {
return forms[form] || forms.other || String(number);
}
if (Array.isArray(forms)) {
// 中文通常只有一种形式
if (locale.startsWith('zh')) {
return forms[0]?.replace('{n}', number) || String(number);
}
// 英语等其他语言
const formIndex = { zero: 0, one: 1, two: 2, few: 3, many: 4, other: 5 }[form];
return forms[formIndex]?.replace('{n}', number) || String(number);
}
return String(number);
}
// 智能复数格式化(支持多种语言)
smartPlural(number, translations) {
const locale = this.pluralRules.resolvedOptions().locale;
const form = this.getPluralForm(number);
if (translations[locale]?.[form]) {
return translations[locale][form].replace('{n}', number);
}
if (translations[locale]?.other) {
return translations[locale].other.replace('{n}', number);
}
// 回退到英语
if (translations.en?.[form]) {
return translations.en[form].replace('{n}', number);
}
return String(number);
}
}
// 使用示例
const pluralizer = new PluralizationService('en');
console.log(pluralizer.formatWithPlural(1, ['apple', 'apples'])); // "apple"
console.log(pluralizer.formatWithPlural(5, ['apple', 'apples'])); // "apples"
19. Proxy API - 元编程拦截器
示例1:数据验证代理
javascript
class ValidatorProxy {
constructor(target, rules = {}) {
this.rules = rules;
return new Proxy(target, {
set: (obj, prop, value) => {
if (this.validate(prop, value)) {
obj[prop] = value;
return true;
}
return false;
}
});
}
validate(prop, value) {
const rule = this.rules[prop];
if (!rule) return true;
if (rule.required && (value === null || value === undefined || value === '')) {
throw new Error(`${prop} 是必填字段`);
}
if (rule.type && typeof value !== rule.type) {
throw new Error(`${prop} 必须是 ${rule.type} 类型`);
}
if (rule.min !== undefined && value < rule.min) {
throw new Error(`${prop} 不能小于 ${rule.min}`);
}
if (rule.max !== undefined && value > rule.max) {
throw new Error(`${prop} 不能大于 ${rule.max}`);
}
if (rule.pattern && !rule.pattern.test(value)) {
throw new Error(`${prop} 格式不正确`);
}
return true;
}
}
// 使用示例
const userRules = {
name: { type: 'string', required: true, min: 2, max: 50 },
age: { type: 'number', min: 0, max: 150 },
email: { type: 'string', pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ }
};
const user = new ValidatorProxy({}, userRules);
user.name = 'John Doe'; // 成功
user.age = 200; // 抛出错误:age 不能大于 150
示例2:响应式状态管理
javascript
class ReactiveState {
constructor(initialState = {}) {
this.state = { ...initialState };
this.subscribers = new Set();
this.proxy = this.createProxy();
}
createProxy() {
return new Proxy(this.state, {
set: (target, prop, value) => {
const oldValue = target[prop];
target[prop] = value;
if (oldValue !== value) {
this.notifySubscribers(prop, value, oldValue);
}
return true;
},
get: (target, prop) => {
if (prop in target) {
return target[prop];
}
return undefined;
}
});
}
subscribe(callback) {
this.subscribers.add(callback);
return () => this.subscribers.delete(callback);
}
notifySubscribers(prop, newValue, oldValue) {
this.subscribers.forEach(callback => {
callback(prop, newValue, oldValue);
});
}
getState() {
return { ...this.state };
}
setState(updater) {
if (typeof updater === 'function') {
const newState = updater(this.state);
Object.assign(this.state, newState);
} else {
Object.assign(this.state, updater);
}
}
}
// 使用示例
const store = new ReactiveState({ count: 0, user: null });
const unsubscribe = store.subscribe((prop, newValue, oldValue) => {
console.log(`${prop} 从 ${oldValue} 变为 ${newValue}`);
});
store.proxy.count = 1; // 触发订阅回调
store.proxy.user = { name: 'John' }; // 触发订阅回调
示例3:方法调用日志和性能监控
javascript
function createLoggingProxy(target, options = {}) {
const {
logCalls = true,
logArguments = true,
logReturn = true,
measurePerformance = false
} = options;
return new Proxy(target, {
get: (obj, prop) => {
const value = obj[prop];
if (typeof value === 'function') {
return new Proxy(value, {
apply: (fn, thisArg, args) => {
const startTime = measurePerformance ? performance.now() : 0;
if (logCalls) {
console.log(`调用方法: ${prop}`);
}
if (logArguments && args.length > 0) {
console.log(`参数:`, args);
}
try {
const result = Reflect.apply(fn, thisArg, args);
if (logReturn) {
console.log(`返回值:`, result);
}
if (measurePerformance) {
const duration = performance.now() - startTime;
console.log(`执行时间: ${duration.toFixed(2)}ms`);
}
return result;
} catch (error) {
console.error(`方法 ${prop} 调用失败:`, error);
throw error;
}
}
});
}
return value;
}
});
}
// 使用示例
class Calculator {
add(a, b) {
return a + b;
}
multiply(a, b) {
return a * b;
}
}
const loggedCalculator = createLoggingProxy(new Calculator(), {
logCalls: true,
logArguments: true,
logReturn: true,
measurePerformance: true
});
loggedCalculator.add(2, 3); // 会输出详细的调用信息
20. Reflect API - 反射操作工具集
示例1:安全的属性操作
javascript
class SafeObjectOperator {
constructor(target) {
this.target = target;
}
getProperty(prop, defaultValue = null) {
if (Reflect.has(this.target, prop)) {
return Reflect.get(this.target, prop);
}
return defaultValue;
}
setProperty(prop, value) {
return Reflect.set(this.target, prop, value);
}
deleteProperty(prop) {
if (Reflect.has(this.target, prop)) {
return Reflect.deleteProperty(this.target, prop);
}
return false;
}
hasProperty(prop) {
return Reflect.has(this.target, prop);
}
getOwnPropertyDescriptor(prop) {
return Reflect.getOwnPropertyDescriptor(this.target, prop);
}
defineProperty(prop, attributes) {
return Reflect.defineProperty(this.target, prop, attributes);
}
// 批量操作
batchUpdate(updates) {
const results = [];
for (const [prop, value] of Object.entries(updates)) {
results.push(this.setProperty(prop, value));
}
return results.every(result => result === true);
}
// 安全的方法调用
invokeMethod(methodName, ...args) {
if (typeof this.target[methodName] === 'function') {
return Reflect.apply(this.target[methodName], this.target, args);
}
throw new Error(`方法 ${methodName} 不存在`);
}
}
// 使用示例
const obj = { name: 'John', age: 30 };
const safeObj = new SafeObjectOperator(obj);
console.log(safeObj.getProperty('name')); // 'John'
console.log(safeObj.getProperty('email', 'unknown')); // 'unknown'
safeObj.setProperty('email', 'john@example.com');
示例2:元编程工具函数
javascript
class MetaProgrammingUtils {
static createImmutableProxy(target) {
return new Proxy(target, {
set: () => {
throw new Error('此对象是不可变的');
},
deleteProperty: () => {
throw new Error('此对象是不可变的');
},
defineProperty: () => {
throw new Error('此对象是不可变的');
}
});
}
static createObservableObject(target, onChange) {
return new Proxy(target, {
set: (obj, prop, value) => {
const oldValue = obj[prop];
const success = Reflect.set(obj, prop, value);
if (success && oldValue !== value) {
onChange(prop, value, oldValue);
}
return success;
},
deleteProperty: (obj, prop) => {
const oldValue = obj[prop];
const success = Reflect.deleteProperty(obj, prop);
if (success) {
onChange(prop, undefined, oldValue);
}
return success;
}
});
}
static deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (obj instanceof Array) {
return obj.map(item => this.deepClone(item));
}
if (typeof obj === 'object') {
const clone = {};
const keys = Reflect.ownKeys(obj);
for (const key of keys) {
const descriptor = Reflect.getOwnPropertyDescriptor(obj, key);
if (descriptor) {
if (descriptor.value && typeof descriptor.value === 'object') {
descriptor.value = this.deepClone(descriptor.value);
}
Reflect.defineProperty(clone, key, descriptor);
}
}
return clone;
}
return obj;
}
static mergeObjects(...objects) {
return objects.reduce((result, obj) => {
if (obj && typeof obj === 'object') {
const keys = Reflect.ownKeys(obj);
for (const key of keys) {
const descriptor = Reflect.getOwnPropertyDescriptor(obj, key);
if (descriptor) {
Reflect.defineProperty(result, key, descriptor);
}
}
}
return result;
}, {});
}
}
示例3:高级反射模式
javascript
class AdvancedReflectPatterns {
// 方法装饰器工厂
static createMethodDecorator(decoratorFunc) {
return (target, propertyKey, descriptor) => {
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
return decoratorFunc.call(this, originalMethod, args, {
target,
propertyKey,
descriptor
});
};
return descriptor;
};
}
// 属性访问拦截器
static createAccessInterceptor(target, interceptor) {
return new Proxy(target, {
get: (obj, prop) => {
const value = Reflect.get(obj, prop);
return interceptor.get ? interceptor.get(prop, value) : value;
},
set: (obj, prop, value) => {
const newValue = interceptor.set ? interceptor.set(prop, value) : value;
return Reflect.set(obj, prop, newValue);
},
has: (obj, prop) => {
const result = Reflect.has(obj, prop);
return interceptor.has ? interceptor.has(prop, result) : result;
}
});
}
// 动态方法混入
static mixinMethods(target, methods) {
for (const [methodName, method] of Object.entries(methods)) {
if (typeof method === 'function') {
Reflect.defineProperty(target, methodName, {
value: method,
writable: true,
enumerable: false,
configurable: true
});
}
}
return target;
}
// 条件方法调用
static createConditionalInvoker(conditions) {
return new Proxy({}, {
get: (_, prop) => {
return (...args) => {
const condition = conditions[prop];
if (condition && typeof condition === 'function') {
return condition(...args);
}
throw new Error(`条件方法 ${prop} 未定义`);
};
}
});
}
}
// 使用示例:创建日志装饰器
const logDecorator = AdvancedReflectPatterns.createMethodDecorator(
function (originalMethod, args, context) {
console.log(`调用方法: ${context.propertyKey}`, args);
const result = Reflect.apply(originalMethod, this, args);
console.log(`方法返回:`, result);
return result;
}
);
class ExampleClass {
@logDecorator
calculate(a, b) {
return a + b;
}
}
🎯 终极总结:掌握现代API,成为前端高手
通过这20个现代JavaScript API的深入学习,你已经掌握了前端开发的核心武器库。每个API都代表着Web开发的一个重要方向:
- 性能优化:Intersection Observer、Resize Observer、Performance API
- 数据处理:Fetch、IndexedDB、File API
- 用户体验:WebSocket、Notification、Clipboard、Geolocation
- 多媒体:Canvas、Web Audio、WebRTC
- 元编程:Proxy、Reflect、Mutation Observer
- 国际化:Intl API
- 现代化:Service Worker、Web Workers
🔥 立即行动建议:
- 选择3个API 在下一个项目中立即使用
- 创建个人项目 实践这些高级特性
- 分享知识 在团队中推广这些最佳实践
- 持续学习 关注新的Web标准和发展
记住:真正的 mastery 来自于实践。不要只是阅读,而是要动手编码!🚀
祝你编码愉快,早日成为前端大神!
本文介绍的API均在现代浏览器中得到良好支持,建议在生产环境中使用时做好兼容性处理。