深入理解 ES6+ 新特性
ECMAScript 6 (简称 ES6) 是 JavaScript 语言的一个重大更新,加入了许多新特性,这些特性极大地提高了开发效率、代码可读性和功能表达能力。本文将围绕以下几个核心特性展开:箭头函数、解构赋值、模块化、Set 和 Map、WeakSet 和 WeakMap,以及其他重要的 ES6 特性。
一、箭头函数 (Arrow Functions)
箭头函数是一种更简洁的函数书写方式,同时它绑定了词法作用域中的 this
,避免了手动绑定的麻烦。
基本语法
// 普通函数
const add = function(a, b) {
return a + b;
};
// 箭头函数
const add = (a, b) => a + b;
特性
- 简洁语法:省略
function
关键字,且单行返回值可以省略{}
和return
。 - 词法作用域绑定的
this
:箭头函数的this
由定义时的上下文决定,而不是调用时。
示例:this
绑定
function Timer() {
this.seconds = 0;
setInterval(() => {
this.seconds++;
console.log(this.seconds); // this 指向 Timer 实例
}, 1000);
}
new Timer();
注意事项
- 不能用作构造函数。
- 不能使用
arguments
对象(可以用 rest 参数替代)。
二、解构赋值 (Destructuring Assignment)
解构赋值允许从数组或对象中提取值,并将其赋值给变量,语法简洁且易读。
数组解构
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
// 默认值
const [x, y = 10] = [5];
console.log(x, y); // 5 10
对象解构
const person = { name: 'Alice', age: 25 };
const { name, age } = person;
console.log(name, age); // Alice 25
// 重命名变量
const { name: username } = person;
console.log(username); // Alice
嵌套解构
const obj = { a: { b: 1 } };
const { a: { b } } = obj;
console.log(b); // 1
三、模块化 (Modules)
模块化是 ES6 引入的重要特性,原生支持模块语法 (import/export
),提高了代码的复用性和可维护性。
导出模块
命名导出
// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
默认导出
// math.js
export default function multiply(a, b) {
return a * b;
}
导入模块
// app.js
import { add, subtract } from './math.js';
import multiply from './math.js';
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
注意事项
import/export
是静态分析的,必须位于模块的顶层。- 默认导出与命名导出可以共存,但推荐一致性使用。
四、Set 和 Map
Set
Set
是一种数据结构,存储的是唯一值,且值是有序的。
基本操作
const set = new Set([1, 2, 3, 3]);
console.log(set); // Set { 1, 2, 3 }
set.add(4);
set.delete(2);
console.log(set.has(1)); // true
console.log(set.size); // 3
Map
Map
是键值对集合,键可以是任意类型。
基本操作
const map = new Map();
map.set('name', 'Alice');
map.set('age', 25);
console.log(map.get('name')); // Alice
console.log(map.has('age')); // true
map.delete('age');
console.log(map.size); // 1
五、WeakSet 和 WeakMap
WeakSet
WeakSet
类似于 Set
,但只能存储对象,并且是弱引用,不会阻止垃圾回收。
基本操作
const ws = new WeakSet();
const obj = { key: 'value' };
ws.add(obj);
console.log(ws.has(obj)); // true
// 如果 obj 被垃圾回收,WeakSet 中也会移除
WeakMap
WeakMap
是键为对象、值可以是任意类型的集合。键是弱引用,适合存储与对象关联的私有数据。
基本操作
const wm = new WeakMap();
const obj = {};
wm.set(obj, 'private data');
console.log(wm.get(obj)); // private data
// 如果 obj 被垃圾回收,WeakMap 中也会移除
六、其他重要 ES6 特性
1. 模板字符串 (Template Literals)
模板字符串用反引号 (``) 包裹,支持多行文本和嵌入表达式。
const name = 'Alice';
const age = 25;
const message = `Hello, my name is ${name} and I am ${age} years old.`;
console.log(message);
2. 默认参数 (Default Parameters)
在函数定义时为参数设置默认值。
function greet(name = 'Guest') {
console.log(`Hello, ${name}`);
}
greet(); // Hello, Guest
greet('Alice'); // Hello, Alice
3. 展开运算符 (Spread Operator)
展开运算符 (...
) 用于展开数组或对象。
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };
console.log(obj2); // { a: 1, b: 2, c: 3 }
4. Rest 参数 (Rest Parameters)
用于接收函数的剩余参数。
function sum(...nums) {
return nums.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
5. Class (类)
ES6 引入了 class
语法,使面向对象编程更易读。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
}
const alice = new Person('Alice', 25);
alice.greet(); // Hello, my name is Alice.
6. Promise
Promise 用于处理异步操作,避免了回调地狱。
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => resolve('Data fetched'), 1000);
});
fetchData.then(data => console.log(data)); // Data fetched
7. Symbol
Symbol
是一种唯一的值,常用于对象的属性键。
const key = Symbol('key');
const obj = { [key]: 'value' };
console.log(obj[key]); // value
七、总结
- 箭头函数 提供了更简洁的语法,同时绑定了词法作用域的
this
。 - 解构赋值 提供