作为一名前端开发者,熟练运用 ES6+ 特性是基本功。本文精选最常用、最实用的JavaScript 新特性,结合实际开发场景,帮你攻克开发难点,提升代码质量。告别繁琐的老式写法,拥抱现代JavaScript。
// 对象解构
const user = {
name: 'Tom',
age: 25,
address: {
city: 'Shanghai',
street: 'Nanjing Road'
}
};
// 基础解构
const { name, age } = user;
// 深层解构
const { address: { city } } = user;
// 设置默认值
const { country = 'China' } = user;
// 数组解构
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// 对象合并
const defaultConfig = { theme: 'dark', lang: 'en' };
const userConfig = { theme: 'light' };
const config = { ...defaultConfig, ...userConfig };
// 数组操作
const nums = [1, 2, 3];
const moreNums = [...nums, 4, 5]; // [1, 2, 3, 4, 5]
// 函数参数
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
// 之前的写法
const street = user && user.address && user.address.street;
// 现代写法
const street = user?.address?.street;
// 数组使用
const first = arr?.[0];
// 函数调用
const result = func?.();
// 之前的写法
const value = data || 'default'; // 0, '', false 都会被替换
// 现代写法
const value = data ?? 'default'; // 只有 null 和 undefined 会被替换
const name = 'Tom';
const age = 25;
// 基础用法
const greeting = `Hello ${name}, you are ${age} years old!`;
// 多行文本
const html = `
${name}
Age: ${age}
`;
// 标签模板
function highlight(strings, ...values) {
return strings.reduce((result, str, i) =>
`${result}${str}${values[i] ? `${values[i]}` : ''}`
, '');
}
const highlighted = highlight`The name is ${name}!`;
// Promise 链式调用
fetch('/api/user')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// async/await 写法
async function getUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
// Promise 并行
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
// Object 新方法
const obj = { name: 'Tom', age: 25 };
Object.entries(obj); // [['name', 'Tom'], ['age', 25]]
Object.fromEntries([['name', 'Tom'], ['age', 25]]); // { name: 'Tom', age: 25 }
// Array 新方法
const arr = [1, 2, 3, 4, 5];
// find 和 findLast
const found = arr.find(x => x > 3); // 4
const foundLast = arr.findLast(x => x > 3); // 5
// flat 和 flatMap
const nested = [1, [2, 3], [4, [5]]];
nested.flat(2); // [1, 2, 3, 4, 5]
// at - 支持负数索引
arr.at(-1); // 5
class User {
#privateField = 'private';
#privateMethod() {
return 'private method';
}
publicMethod() {
console.log(this.#privateField);
console.log(this.#privateMethod());
}
}
// Map - 键值对集合,任何类型都可以作为键
const map = new Map();
map.set('key', 'value');
map.set(objKey, 'value'); // 对象也可以作为键
// Map 的常用操作
for (let [key, value] of map) {
console.log(`${key} = ${value}`);
}
// WeakMap - 弱引用版本的Map
const weakMap = new WeakMap(); // 用于防止内存泄漏
// Set - 值的集合,自动去重
const set = new Set([1, 2, 2, 3, 3]); // {1, 2, 3}
// Set 的实用操作
const intersection = new Set([...set1].filter(x => set2.has(x)));
const difference = new Set([...set1].filter(x => !set2.has(x)));
// 数组分组(ES2023)
const items = [
{type: 'fruit', name: 'apple'},
{type: 'vegetable', name: 'carrot'},
{type: 'fruit', name: 'banana'},
];
const grouped = Object.groupBy(items, item => item.type);
/*
{
fruit: [{type: 'fruit', name: 'apple'}, {type: 'fruit', name: 'banana'}],
vegetable: [{type: 'vegetable', name: 'carrot'}]
}
*/
// 数组操作新方法
const arr = [1, 2, 3, 4, 5];
// toSorted, toReversed - 不修改原数组的版本
const sorted = arr.toSorted((a, b) => b - a);
const reversed = arr.toReversed();
// with - 不修改原数组的替换
const newArr = arr.with(2, 10); // [1, 2, 10, 4, 5]
// replaceAll
const str = 'hello hello';
str.replaceAll('hello', 'hi'); // 'hi hi'
// matchAll
const regex = /t(e)(st(\d?))/g;
const text = 'test1 test2 test3';
const matches = [...text.matchAll(regex)];
// padStart/padEnd
'5'.padStart(2, '0'); // '05'
'hello'.padEnd(10, '*'); // 'hello*****'
class Product {
// 公共字段声明
name;
price;
// 私有字段
#stock;
// 静态私有字段
static #count = 0;
// 静态公共方法
static createProduct(name, price) {
return new Product(name, price);
}
// 类字段初始化器
tax = 0.1;
// getter/setter
get inStock() {
return this.#stock > 0;
}
// 私有方法
#calculateDiscount() {
return this.price * 0.1;
}
}
// 函数参数默认值
function greet(name = 'Guest', greeting = `Hello`) {
return `${greeting}, ${name}!`;
}
// 箭头函数和this
class Handler {
constructor() {
this.value = 42;
}
normal() {
setTimeout(function() {
console.log(this.value); // undefined
});
}
arrow() {
setTimeout(() => {
console.log(this.value); // 42
});
}
}
// 函数组合
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const add10 = x => x + 10;
const multiply2 = x => x * 2;
const combined = pipe(add10, multiply2);
// 命名捕获组
const regex = /(?\d{4})-(?\d{2})-(?\d{2})/;
const match = '2024-02-07'.match(regex);
console.log(match.groups.year); // 2024
// 后行断言
const price = '$123.45'.match(/(?<=\$)\d+\.\d+/)[0];
// Unicode 属性转义
const regex = /\p{Emoji}/u;
console.log(regex.test('')); // true
// 动态导入
const loadModule = async () => {
const module = await import('./module.js');
module.doSomething();
};
// 模块命名空间导出
export * as utils from './utils.js';
// 导出默认值和具名导出组合
export { default as Main, utilities } from './module.js';
// 管道操作
const double = n => n * 2;
const increment = n => n + 1;
const square = n => n * n;
// 函数式编程管道
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const compute = pipe(double, increment, square);
console.log(compute(3)); // ((3 * 2 + 1) ^ 2) = 49
// 装饰器模式(Stage 3提案)
function log(target, name, descriptor) {
// 方法装饰器
}
// 对象属性监听
const handler = {
get: function(target, prop) {
console.log(`Accessing ${prop}`);
return target[prop];
}
};
const proxy = new Proxy({}, handler);
// 自定义错误类
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = 'ValidationError';
}
}
// 异步错误处理
async function fetchData() {
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new ValidationError('API请求失败');
}
return await response.json();
} catch (error) {
if (error instanceof ValidationError) {
// 处理验证错误
} else {
// 处理其他错误
}
} finally {
// 清理工作
}
}
1. 链式可选操作
// 组合使用可选链和空值合并
const username = data?.user?.profile?.name ?? 'Anonymous';
2. 动态对象属性
const field = 'name';
const value = 'Tom';
const user = {
[field]: value
};
3. 数组去重
const unique = [...new Set([1, 1, 2, 3, 3])]; // [1, 2, 3]
现代JavaScript的这些特性不仅让代码更简洁,还提供了很多强大的功能:
建议: