ES2018 和 ES2019 为 JavaScript 带来了新的特性和语法改进。
// 异步生成器函数
async function* asyncGenerator() {
let i = 0
while (i < 3) {
yield new Promise(resolve => setTimeout(() => resolve(i++), 1000))
}
}
// 使用异步迭代
async function consumeAsyncGenerator() {
for await (let value of asyncGenerator()) {
console.log(value) // 0, 1, 2 (每秒一个)
}
}
consumeAsyncGenerator()// finally 方法总是会执行
function doSomething() {
return fetch('/api/data')
.then(response => response.json())
.catch(error => console.error('Fetch failed:', error))
.finally(() => {
console.log('Cleanup completed')
hideLoadingSpinner()
})
}
// 无论成功还是失败都会执行清理
doSomething().then(data => {
console.log('Data received:', data)
})// s 标志:dotAll 模式
const regex1 = /./s
console.log(regex1.test('\n')) // true (点号匹配换行符)
// 命名捕获组
const regex2 = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const match = '2023-12-25'.match(regex2)
console.log(match.groups) // { year: '2023', month: '12', day: '25' }
// 后行断言
const regex3 = /(?<=@)\w+/ // 匹配 @ 后面的单词
console.log('user@email.com'.match(regex3)) // ['email']
// 前行断言
const regex4 = /\w+(?=\.com)/ // 匹配 .com 前面的单词
console.log('user@email.com'.match(regex4)) // ['email']// 浅拷贝对象
const original = { a: 1, b: 2 }
const copy = { ...original }
// 合并对象
const obj1 = { a: 1, b: 2 }
const obj2 = { c: 3, d: 4 }
const merged = { ...obj1, ...obj2 } // { a: 1, b: 2, c: 3, d: 4 }
// 添加属性
const enhanced = { ...original, c: 3, d: 4 }
// 函数参数
function createUser(name, email, ...options) {
return {
name,
email,
...options
}
}
const user = createUser('John', 'john@example.com', { age: 30, active: true })// 转义序列
const str1 = `Line 1\nLine 2` // 有效的换行
const str2 = `Column 1\tColumn 2` // 有效的制表符
// 标签函数中的转义
function myTag(strings, ...values) {
return strings.reduce((result, str, i) => {
return result + str + (values[i] || '')
}, '')
}
const result = myTag`Hello \u{1F600} World` // 支持 Unicode 转义// flat() 扁平化数组
const nested = [1, [2, [3, [4]]]]
console.log(nested.flat()) // [1, 2, [3, [4]]]
console.log(nested.flat(2)) // [1, 2, 3, [4]]
console.log(nested.flat(Infinity)) // [1, 2, 3, 4]
// flatMap() 先映射再扁平化
const sentences = ['Hello world', 'How are you']
const words = sentences.flatMap(sentence => sentence.split(' '))
console.log(words) // ['Hello', 'world', 'How', 'are', 'you']
// 数值计算示例
const numbers = [1, 2, 3, 4]
const doubled = numbers.flatMap(x => [x, x * 2])
console.log(doubled) // [1, 2, 2, 4, 3, 6, 4, 8]// 从键值对数组创建对象
const entries = [['name', 'John'], ['age', 30], ['city', 'New York']]
const obj = Object.fromEntries(entries)
console.log(obj) // { name: 'John', age: 30, city: 'New York' }
// Map 转换为对象
const map = new Map([['a', 1], ['b', 2], ['c', 3]])
const objFromMap = Object.fromEntries(map)
console.log(objFromMap) // { a: 1, b: 2, c: 3 }
// URL 参数转换为对象
const urlParams = new URLSearchParams('name=John&age=30')
const paramsObj = Object.fromEntries(urlParams)
console.log(paramsObj) // { name: 'John', age: '30' }
// 过滤和转换
const filteredObj = Object.fromEntries(
Object.entries(obj).filter(([key, value]) => typeof value === 'string')
)// 移除开头空白
const str1 = ' Hello World '
console.log(str1.trimStart()) // 'Hello World '
// 移除结尾空白
console.log(str1.trimEnd()) // ' Hello World'
// 链式调用
console.log(str1.trimStart().trimEnd()) // 'Hello World'
// 别名方法
console.log(str1.trimLeft()) // 'Hello World ' (trimStart 的别名)
console.log(str1.trimRight()) // ' Hello World' (trimEnd 的别名)// 获取 Symbol 的描述
const sym1 = Symbol('my symbol')
console.log(sym1.description) // 'my symbol'
const sym2 = Symbol()
console.log(sym2.description) // undefined
const sym3 = Symbol('')
console.log(sym3.description) // ''
// 自定义描述
function createSymbol(description) {
return Symbol(description)
}
const mySymbol = createSymbol('unique identifier')
console.log(mySymbol.description) // 'unique identifier'// 传统的 try-catch
try {
riskyOperation()
} catch (error) {
console.error('An error occurred:', error)
}
// ES2019 可选 catch 绑定
try {
riskyOperation()
} catch {
console.error('An error occurred')
}
// 当不需要访问错误对象时很有用
const results = [
tryProcess(item1),
tryProcess(item2),
tryProcess(item3)
].filter(Boolean)
function tryProcess(item) {
try {
return processItem(item)
} catch {
return null // 静默失败
}
}// JSON.stringify() 改进
const obj = { a: 1, b: 2 }
// 格式化输出
console.log(JSON.stringify(obj, null, 2))
// {
// "a": 1,
// "b": 2
// }
// toJSON 方法支持
class User {
constructor(name, age) {
this.name = name
this.age = age
this.createdAt = new Date()
}
toJSON() {
return {
name: this.name,
age: this.age,
createdAt: this.createdAt.toISOString()
}
}
}
const user = new User('Alice', 25)
console.log(JSON.stringify(user))
// {"name":"Alice","age":25,"createdAt":"2023-12-07T10:30:00.000Z"}// 使用异步迭代处理流数据
async function processLargeFile(file) {
const stream = file.stream()
let totalBytes = 0
for await (const chunk of stream) {
totalBytes += chunk.length
console.log(`Processed ${totalBytes} bytes`)
}
return totalBytes
}
// Promise.finally 清理资源
function fetchWithCleanup(url) {
const controller = new AbortController()
return fetch(url, { signal: controller.signal })
.then(response => response.json())
.finally(() => {
console.log('Request cleanup')
// 清理资源
})
}// 使用展开运算符和 Object.fromEntries
function updateUser(userId, updates) {
const users = getUsersFromStorage()
const updatedUsers = users.map(user =>
user.id === userId
? { ...user, ...updates, updatedAt: new Date() }
: user
)
saveUsersToStorage(updatedUsers)
return updatedUsers.find(user => user.id === userId)
}
// URL 参数处理
function parseQueryParams(url) {
const params = new URL(url).searchParams
return Object.fromEntries(params)
}
const params = parseQueryParams('https://example.com?name=John&age=30')
console.log(params) // { name: 'John', age: '30' }// 解析复杂格式
function parseEmailHeader(header) {
const regex = /(?<name>[^<]+)\s*<?(?<email>[^>\s]+)>?/
const match = header.match(regex)
if (match) {
return {
name: match.groups.name.trim(),
email: match.groups.email
}
}
return null
}
console.log(parseEmailHeader('John Doe <john@example.com>'))
// { name: 'John Doe', email: 'john@example.com' }
// dotAll 模式处理多行文本
function extractCodeBlocks(text) {
const regex = /```[\s\S]*?```/g
return text.match(regex) || []
}ES2018 和 ES2019 为 JavaScript 带来了重要改进:
ES2018:
ES2019:
这些新特性让 JavaScript 更加现代化和易用。