一、ES6 (ES2015) 重要新特性
1. 模板字符串 (Template Literals)
- 使用反引号(``)定义字符串
- 支持多行字符串和插值表达式
// 基本用法
const name = 'Alice';
const greeting = `Hello, ${name}!`; // "Hello, Alice!"
// 多行字符串
const multiLine = `
This is
a multi-line
string
`;
// 标签模板
function tag(strings, ...values) {
console.log(strings); // ["Hello ", "!"]
console.log(values); // ["Alice"]
return strings[0] + values[0].toUpperCase() + strings[1];
}
const result = tag`Hello ${name}!`; // "Hello ALICE!"
2. 箭头函数 (Arrow Functions)
// 基本语法
const add = (a, b) => a + b;
// 单参数可省略括号
const square = x => x * x;
// 无参数需要括号
const sayHi = () => console.log('Hi');
// 返回对象需要用括号包裹
const makePerson = (name, age) => ({ name, age });
// this 绑定示例
const counter = {
count: 0,
increment: function() {
setInterval(() => {
this.count++; // 正确绑定this
console.log(this.count);
}, 1000);
}
};
3. 函数参数增强
默认参数 (Default Parameters)
function greet(name = 'Guest', greeting = 'Hello') {
return `${greeting}, ${name}!`;
}
console.log(greet()); // "Hello, Guest!"
剩余参数 (Rest Parameters)
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6
4. 解构赋值 (Destructuring Assignment)
对象解构
const person = { name: 'John', age: 30, city: 'New York' };
const { name, age } = person;
console.log(name, age); // "John" 30
// 别名
const { name: personName } = person;
console.log(personName); // "John"
// 默认值
const { country = 'USA' } = person;
console.log(country); // "USA"
数组解构
const numbers = [1, 2, 3];
const [first, second] = numbers;
console.log(first, second); // 1 2
// 跳过元素
const [,, third] = numbers;
console.log(third); // 3
// 剩余元素
const [head, ...tail] = numbers;
console.log(tail); // [2, 3]
5. 对象字面量增强
属性简写
const name = 'Alice';
const age = 25;
const person = { name, age }; // { name: 'Alice', age: 25 }
方法简写
const obj = {
// 传统写法
sayHello: function() {},
// 简写写法
sayHi() {},
// 箭头函数
sayBye: () => {}
};
计算属性名
const propKey = 'name';
const obj = {
[propKey]: 'John',
[`get${propKey}`]() {
return this[propKey];
}
};
console.log(obj.getName()); // "John"
二、ES2016 (ES7) 新特性
1. 数组 includes() 方法
const arr = [1, 2, 3];
console.log(arr.includes(2)); // true
console.log(arr.includes(4)); // false
// 与indexOf的区别
console.log([NaN].includes(NaN)); // true
console.log([NaN].indexOf(NaN) !== -1); // false
2. 指数运算符 (**)
console.log(2 ** 3); // 8
console.log(Math.pow(2, 3)); // 8
// 与Math.pow()的区别
console.log((-2) ** 3); // -8
console.log(Math.pow(-2, 3)); // -8
三、ES2017 (ES8) 新特性
1. async/await
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
2. Object.values() / Object.entries()
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.values(obj)); // [1, 2, 3]
console.log(Object.entries(obj)); // [["a", 1], ["b", 2], ["c", 3]]
// 与for...in的区别
for (const [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`);
}
3. 字符串填充方法
console.log('5'.padStart(2, '0')); // "05"
console.log('12'.padStart(2, '0')); // "12"
console.log('abc'.padEnd(5, '*')); // "abc**"
4. 函数参数列表尾逗号
function foo(
param1,
param2, // 允许尾逗号
) {
// ...
}
四、ES2018 (ES9) 新特性
1. 对象扩展运算符
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
// 覆盖属性
const obj3 = { ...obj1, a: 3 }; // { a: 3, b: 2 }
// 浅拷贝
const obj4 = { ...obj1 };
console.log(obj4 === obj1); // false
2. Promise.finally()
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error))
.finally(() => console.log('Request completed'));
3. 正则表达式增强
命名捕获组
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = re.exec('2023-05-15');
console.log(match.groups.year); // "2023"
dotAll 模式 (s 标志)
const re = /foo.bar/s;
console.log(re.test('foo\nbar')); // true
后行断言
console.log(/(?<=\$)\d+/.exec('$100')[0]); // "100" (匹配$后的数字)
console.log(/(?<!\$)\d+/.exec('€100')[0]); // "100" (匹配前面不是$的数字)
五、ES2019 (ES10) 新特性
1. Array.flat() / Array.flatMap()
const arr = [1, [2, [3]]];
console.log(arr.flat()); // [1, 2, [3]]
console.log(arr.flat(2)); // [1, 2, 3]
const sentences = ["Hello world", "Goodbye universe"];
const words = sentences.flatMap(sentence => sentence.split(' '));
console.log(words); // ["Hello", "world", "Goodbye", "universe"]
2. Object.fromEntries()
const entries = [['name', 'John'], ['age', 30]];
const obj = Object.fromEntries(entries);
console.log(obj); // { name: "John", age: 30 }
// 与Object.entries()配合使用
const newObj = Object.fromEntries(
Object.entries(obj).map(([key, value]) => [key, String(value)])
);
3. String.trimStart() / String.trimEnd()
const str = ' hello ';
console.log(str.trimStart()); // "hello "
console.log(str.trimEnd()); // " hello"
4. 可选的 catch 绑定
try {
// ...
} catch { // 不需要指定error参数
console.log('An error occurred');
}
六、ES2020 (ES11) 新特性
1. 可选链操作符 (?.)
const user = { profile: { name: 'John' } };
// 传统写法
const name = user && user.profile && user.profile.name;
// 可选链写法
const name = user?.profile?.name;
// 函数调用
user.sayHi?.(); // 如果sayHi存在则调用
// 数组访问
const firstItem = arr?.[0];
2. 空值合并运算符 (??)
const value = null ?? 'default'; // "default"
const value2 = 0 ?? 'default'; // 0 (与||不同)
// 与||的区别
console.log(0 || 'default'); // "default"
console.log('' || 'default'); // "default"
console.log(false || 'default'); // "default"
3. 动态导入 (Dynamic Import)
// 按需加载模块
button.addEventListener('click', async () => {
const module = await import('./module.js');
module.doSomething();
});
4. BigInt
const bigNum = 9007199254740991n; // 字面量加n
const anotherBigNum = BigInt("9007199254740991");
console.log(bigNum + anotherBigNum); // 18014398509481982n
// 不能与Number混合运算
console.log(bigNum + 1); // TypeError
七、ES2021 (ES12) 新特性
1. 逻辑赋值运算符
// 逻辑或赋值
let a = false;
a ||= true; // a = a || true
// 逻辑与赋值
let b = true;
b &&= false; // b = b && false
// 空值合并赋值
let c = null;
c ??= 'default'; // c = c ?? 'default'
2. String.replaceAll()
const str = 'hello world';
console.log(str.replaceAll('l', 'x')); // "hexxo worxd"
// 之前需要正则表达式
console.log(str.replace(/l/g, 'x')); // "hexxo worxd"
3. Promise.any()
const promises = [
Promise.reject('Error 1'),
Promise.resolve('Success 1'),
Promise.reject('Error 2')
];
Promise.any(promises)
.then(result => console.log(result)) // "Success 1"
.catch(errors => console.log(errors));
4. 数字分隔符
const billion = 1_000_000_000; // 更易读
console.log(billion === 1000000000); // true
八、ES2022 (ES13) 新特性
1. 类字段声明
class Counter {
count = 0; // 实例字段
increment = () => { // 箭头函数方法
this.count++;
};
static version = '1.0'; // 静态字段
}
2. 私有字段和方法
class Person {
#name; // 私有字段
constructor(name) {
this.#name = name;
}
#privateMethod() { // 私有方法
return `Hello, ${this.#name}`;
}
greet() {
console.log(this.#privateMethod());
}
}
const person = new Person('John');
person.greet(); // "Hello, John"
// person.#name; // SyntaxError
3. 静态初始化块
class Translator {
static translations = {
yes: 'ja',
no: 'nein'
};
static englishWords = [];
static germanWords = [];
static { // 静态初始化块
for (const [english, german] of Object.entries(this.translations)) {
this.englishWords.push(english);
this.germanWords.push(german);
}
}
}
4. 顶层 await
// 在模块顶层使用await
const data = await fetchData();
console.log(data);
// 之前需要包装在async函数中
(async () => {
const data = await fetchData();
console.log(data);
})();
九、ES2023 (ES14) 新特性
1. Array.findLast() / Array.findLastIndex()
const numbers = [1, 2, 3, 4, 3, 2, 1];
console.log(numbers.findLast(n => n > 2)); // 3 (最后一个满足条件的元素)
console.log(numbers.findLastIndex(n => n > 2)); // 4 (索引)
2. Hashbang 语法标准化
#!/usr/bin/env node
// 现在ES标准正式支持Shebang语法
console.log('Hello from CLI tool');
3. WeakMap 支持 Symbol 键
const weakMap = new WeakMap();
const key = Symbol('privateData');
const obj = {};
weakMap.set(key, 'secret');
weakMap.set(obj, 'other secret');
console.log(weakMap.get(key)); // "secret"
console.log(weakMap.get(obj)); // "other secret"
十、总结与应用建议
1. 版本特性快速参考
版本 |
重要特性 |
ES6 |
类、模块、箭头函数、模板字符串、解构、Promise、let/const |
ES2016 |
includes()、指数运算符 |
ES2017 |
async/await、Object.values/entries、字符串填充 |
ES2018 |
对象扩展运算符、Promise.finally、正则增强 |
ES2019 |
Array.flat/flatMap、Object.fromEntries、trimStart/End |
ES2020 |
可选链、空值合并、动态导入、BigInt |
ES2021 |
逻辑赋值、replaceAll、Promise.any、数字分隔符 |
ES2022 |
类字段、私有方法、静态块、顶层await |
ES2023 |
Array.findLast、Hashbang、WeakMap Symbol键 |
2. 现代JavaScript开发建议
-
优先使用新语法:如箭头函数、模板字符串、解构赋值等
-
渐进式采用:根据项目环境逐步引入新特性
-
关注兼容性:使用Babel等工具确保代码兼容性
-
代码可读性:合理使用新特性提升代码可读性而非炫技
-
团队一致性:制定团队编码规范统一新特性的使用方式
3. 学习资源推荐
-
官方文档:ECMAScript规范
-
兼容性查询:Can I use
-
实践教程:现代JavaScript教程
-
新特性演示:ES6+示例