🚀 JavaScript 现代特性概览
JavaScript 在过去几年中经历了快速发展,从 ES6 开始引入了许多强大的新特性。这些特性不仅让代码更加简洁优雅,还提升了开发效率和代码可维护性。
📋 本文涵盖的特性
- 解构赋值 - 优雅地提取数据
- 箭头函数 - 简洁的函数语法
- 模板字符串 - 强大的字符串处理
- Promise 和 async/await - 现代异步编程
- 模块系统 - 代码组织和复用
- 新的数据结构 - Map、Set、WeakMap、WeakSet
🎯 解构赋值
解构赋值让我们能够从数组或对象中提取值,并赋给变量。
数组解构
// 基础数组解构
const colors = ['red', 'green', 'blue'];
const [primary, secondary, tertiary] = colors;
console.log(primary); // 'red'
console.log(secondary); // 'green'
console.log(tertiary); // 'blue'
// 跳过元素
const [first, , third] = colors;
console.log(first, third); // 'red' 'blue'
// 默认值
const [a, b, c, d = 'yellow'] = colors;
console.log(d); // 'yellow'
// 剩余元素
const [head, ...tail] = colors;
console.log(head); // 'red'
console.log(tail); // ['green', 'blue']
对象解构
// 基础对象解构
const user = {
name: 'Alice',
age: 30,
email: 'alice@example.com',
address: {
city: 'Shanghai',
country: 'China'
}
};
const { name, age, email } = user;
console.log(name, age, email); // 'Alice' 30 'alice@example.com'
// 重命名变量
const { name: userName, age: userAge } = user;
console.log(userName, userAge); // 'Alice' 30
// 嵌套解构
const { address: { city, country } } = user;
console.log(city, country); // 'Shanghai' 'China'
// 函数参数解构
function greetUser({ name, age }) {
return `Hello ${name}, you are ${age} years old!`;
}
console.log(greetUser(user)); // 'Hello Alice, you are 30 years old!'
⚡ 箭头函数
箭头函数提供了更简洁的函数语法,并且不绑定自己的 this
。
// 传统函数 vs 箭头函数
const traditional = function(x, y) {
return x + y;
};
const arrow = (x, y) => x + y;
// 单参数可省略括号
const square = x => x * x;
// 无参数需要空括号
const random = () => Math.random();
// 多行箭头函数
const processData = (data) => {
const filtered = data.filter(item => item.active);
const mapped = filtered.map(item => item.value);
return mapped.reduce((sum, val) => sum + val, 0);
};
// 返回对象字面量
const createUser = (name, age) => ({ name, age, id: Date.now() });
// 高阶函数中的应用
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(evens); // [2, 4]
console.log(sum); // 15
📝 模板字符串
模板字符串使用反引号,支持多行字符串和表达式插值。
const name = 'CodeBuddy';
const version = '2.0';
const features = ['极光背景', '玻璃拟态', '响应式设计'];
// 基础插值
const greeting = `欢迎使用 ${name} v${version}!`;
console.log(greeting);
// 多行字符串
const multiLine = `
这是一个多行字符串
可以包含换行符
非常适合模板生成
`;
// 表达式计算
const calculation = `2 + 3 = ${2 + 3}`;
console.log(calculation); // '2 + 3 = 5'
// 函数调用
const formatDate = (date) => date.toLocaleDateString('zh-CN');
const today = `今天是 ${formatDate(new Date())}`;
// 条件表达式
const status = 'online';
const userStatus = `用户状态: ${status === 'online' ? '在线' : '离线'}`;
// 标签模板
function highlight(strings, ...values) {
return strings.reduce((result, string, i) => {
const value = values[i] ? `<mark>${values[i]}</mark>` : '';
return result + string + value;
}, '');
}
const highlighted = highlight`用户 ${name} 正在使用版本 ${version}`;
console.log(highlighted);
// '用户 <mark>CodeBuddy</mark> 正在使用版本 <mark>2.0</mark>'
🔄 现代异步编程
Promise 基础
// 创建 Promise
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.5;
if (success) {
resolve({ data: '获取成功', timestamp: Date.now() });
} else {
reject(new Error('获取失败'));
}
}, 1000);
});
};
// 使用 Promise
fetchData()
.then(result => {
console.log('成功:', result);
return result.data;
})
.then(data => {
console.log('处理数据:', data);
})
.catch(error => {
console.error('错误:', error.message);
})
.finally(() => {
console.log('请求完成');
});
async/await
// async 函数
async function fetchUserData(userId) {
try {
// 并行请求
const [user, posts, comments] = await Promise.all([
fetch(`/api/users/${userId}`).then(r => r.json()),
fetch(`/api/users/${userId}/posts`).then(r => r.json()),
fetch(`/api/users/${userId}/comments`).then(r => r.json())
]);
return {
user,
posts,
comments,
summary: {
totalPosts: posts.length,
totalComments: comments.length
}
};
} catch (error) {
console.error('获取用户数据失败:', error);
throw error;
}
}
// 使用 async/await
async function displayUserProfile(userId) {
try {
const userData = await fetchUserData(userId);
console.log('用户资料:', userData);
} catch (error) {
console.error('显示用户资料失败:', error);
}
}
// 异步迭代
async function processItems(items) {
for (const item of items) {
try {
const result = await processItem(item);
console.log(`处理完成: ${item.id}`, result);
} catch (error) {
console.error(`处理失败: ${item.id}`, error);
}
}
}
📦 模块系统
ES6 模块导出
// utils.js - 命名导出
export const PI = 3.14159;
export function calculateArea(radius) {
return PI * radius * radius;
}
export class Calculator {
add(a, b) {
return a + b;
}
subtract(a, b) {
return a - b;
}
}
// 默认导出
export default class MathUtils {
static factorial(n) {
return n <= 1 ? 1 : n * this.factorial(n - 1);
}
}
ES6 模块导入
// 命名导入
import { PI, calculateArea, Calculator } from './utils.js';
// 默认导入
import MathUtils from './utils.js';
// 混合导入
import MathUtils, { PI, calculateArea } from './utils.js';
// 重命名导入
import { calculateArea as getCircleArea } from './utils.js';
// 导入所有
import * as Utils from './utils.js';
// 动态导入
async function loadModule() {
const module = await import('./utils.js');
const area = module.calculateArea(5);
console.log('面积:', area);
}
🗂️ 新的数据结构
Map 和 Set
// Map - 键值对集合
const userRoles = new Map();
userRoles.set('alice', 'admin');
userRoles.set('bob', 'user');
userRoles.set('charlie', 'moderator');
console.log(userRoles.get('alice')); // 'admin'
console.log(userRoles.has('bob')); // true
console.log(userRoles.size); // 3
// 遍历 Map
for (const [user, role] of userRoles) {
console.log(`${user}: ${role}`);
}
// Set - 唯一值集合
const uniqueNumbers = new Set([1, 2, 3, 3, 4, 4, 5]);
console.log(uniqueNumbers); // Set {1, 2, 3, 4, 5}
uniqueNumbers.add(6);
uniqueNumbers.delete(1);
console.log(uniqueNumbers.has(3)); // true
// 数组去重
const numbers = [1, 2, 2, 3, 3, 4, 5, 5];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4, 5]
WeakMap 和 WeakSet
// WeakMap - 弱引用键值对
const privateData = new WeakMap();
class User {
constructor(name) {
this.name = name;
// 私有数据存储
privateData.set(this, {
id: Math.random().toString(36),
createdAt: new Date()
});
}
getId() {
return privateData.get(this).id;
}
getCreatedAt() {
return privateData.get(this).createdAt;
}
}
const user = new User('Alice');
console.log(user.getId()); // 随机ID
🛠️ 实用工具函数
结合现代特性创建实用工具:
// 防抖函数
const debounce = (func, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
};
// 节流函数
const throttle = (func, limit) => {
let inThrottle;
return (...args) => {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
};
// 深拷贝
const deepClone = (obj) => {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Array) return obj.map(item => deepClone(item));
if (typeof obj === 'object') {
const clonedObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = deepClone(obj[key]);
}
}
return clonedObj;
}
};
// 管道函数
const pipe = (...functions) => (value) =>
functions.reduce((acc, func) => func(acc), value);
// 使用示例
const addOne = x => x + 1;
const double = x => x * 2;
const square = x => x * x;
const transform = pipe(addOne, double, square);
console.log(transform(3)); // ((3 + 1) * 2)² = 64
📈 性能优化技巧
// 使用 Object.freeze 防止对象修改
const config = Object.freeze({
API_URL: 'https://api.example.com',
TIMEOUT: 5000,
RETRIES: 3
});
// 使用 WeakMap 缓存计算结果
const memoCache = new WeakMap();
function expensiveCalculation(obj) {
if (memoCache.has(obj)) {
return memoCache.get(obj);
}
// 模拟复杂计算
const result = obj.value * Math.random();
memoCache.set(obj, result);
return result;
}
// 使用 requestIdleCallback 优化性能
function performOptionalWork() {
if ('requestIdleCallback' in window) {
requestIdleCallback((deadline) => {
while (deadline.timeRemaining() > 0) {
// 执行非关键任务
doOptionalWork();
}
});
} else {
// 降级方案
setTimeout(doOptionalWork, 1);
}
}
🎉 总结
JavaScript 的现代特性大大提升了开发体验:
- 解构赋值 让数据提取更优雅
- 箭头函数 简化了函数语法
- 模板字符串 增强了字符串处理能力
- async/await 让异步代码更易读
- 模块系统 改善了代码组织
- 新数据结构 提供了更多选择
掌握这些特性不仅能写出更简洁的代码,还能提升应用性能和可维护性。在实际项目中,建议根据浏览器兼容性要求合理使用这些特性。
💡 提示:现代 JavaScript 特性虽然强大,但要注意浏览器兼容性。可以使用 Babel 等工具进行转译,确保代码在目标环境中正常运行。