JavaScript ES6+ 哪些常用新特性?
1 模板字符串(`)
使用 反引号(`)包裹,支持 嵌入变量、表达式 和 多行字符串。
1.1 嵌入 变量
// 示例代码 1
const name = "张三";
const age = 25;
const message = `
你好,我的名字是 ${name}。
我今年 ${age} 岁。
我喜欢编程。
`;
console.log(message);
/*
你好,我的名字是 张三。
我今年 25 岁。
我喜欢编程。
*/
1.2 嵌入 函数或表达式
// 示例代码 2
const add = (a, b) => a + b;
const result = `
计算 5 + 10 的结果是:${add(5, 10)}
`;
console.log(result);
1.3 嵌入 多行字符串
// 示例代码 3
const multiLineString = `
这是第一行
这是第二行
这是第三行
`;
console.log(multiLineString);
/*
这是第一行
这是第二行
这是第三行
*/
2 对象字面量增强(Enhanced Object Literals)
允许直接使用 变量 作为 对象属性名 或 方法名。
// 示例代码 4
const name = "Alice";
const age = 25;
const obj = {
name, // 属性名简写,等价于 name: name
age, // 属性名简写,等价于 age: age
// 方法简写
greet() {
return `Hello, ${this.name}`;
}
/*
等价于
greet: function() {
return `Hello, ${this.name}`;
}
*/
};
console.log(obj.name); // 输出:Alice
console.log(obj.age); // 输出:25
console.log(obj.greet()); // 输出:Hello, Alice
3 模块化(Modules)
模块化 是 现代编程中 一种重要的 组织代码 的 方式,它将代码分割为 独立的、可重用 的 模块,每个模块 通常实现 一个特定的 功能 或 逻辑。
使用 import 和 export 实现 模块化。
3.1 主要使用场景
1 代码组织和复用
- 大型 项目开发:当 代码量 较大时,将功能 分解为 多个模块 可以提升 代码的 可读性 和 可维护性。
- 跨项目 共享 代码:通用功能模块(如 工具函数库、API 封装 等)可以在 多个项目中 复用。
// 示例代码 5
// math.js
export const add = (a, b) => a + b;
// main.js
import { add } from "./math.js";
console.log(add(2, 3)); // 输出:5
2 分离关注点
- 前端 项目开发:将 业务逻辑、视图渲染、样式管理 分离到 不同的模块。
- 后端 项目开发:分离 路由、控制器、服务层代码,保持 逻辑独立。
// 示例代码 6
// api.js
export async function fetchData(url) {
const response = await fetch(url);
return await response.json();
}
// component.js
import { fetchData } from './api.js';
fetchData('/api/data').then(data => console.log(data));
3 团队协作
-
多人协作开发时,不同开发者 负责 不同的模块,减少 代码冲突 的风险。
-
通过 模块接口 清晰地定义 输入输出,每个开发者 专注于 自己的 模块实现。
// 示例代码 7
// 前端开发中,一个人负责 UI 组件模块,另一个人负责状态管理模块,通过模块接口进行协作
// uiComponent.js
export const renderButton = () => {
console.log('Rendering button');
};
// stateManager.js
export const updateState = (newState) => {
console.log('Updating state to', newState);
};
【具体实例代码,等待同步......】
4 按需加载(代码分割)
- 在 Web 应用中,按需加载模块(即代码分割)可以 减少 首次加载时间,提升性能。
- 只加载 当前页面 或 功能所需的 代码,而不是 一次性加载 所有模块。
// 示例代码 8
// 动态导入模块
// mathUtils.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// main.js
const loadMathUtils = async () => {
// 动态导入模块
const mathUtils = await import('./mathUtils.js');
console.log(mathUtils.add(2, 3)); // 输出:5
console.log(mathUtils.subtract(5, 2)); // 输出:3
};
document.querySelector('#loadBtn').addEventListener('click', loadMathUtils);
在其他模块中,只能访问 publicFunction,无法访问 privateVar。
5 提升代码安全性
- 避免 全局变量 冲突,将代码 封装在 模块内。
- 控制 模块的 导出内容,隐藏 不需要 暴露的 实现细节。
// 示例代码 9
// myModule.js
const privateVar = 'This is private';
export const publicFunction = () => console.log('This is public');
6 第三方库的集成
- 通过 模块化方式 引入 和 管理 第三方依赖(如 lodash、axios 等)。
- 管理 依赖版本,减少 全局污染。
// 示例代码 10
// 使用 import 从 npm 包中加载模块:
import _ from 'lodash';
console.log(_.chunk([1, 2, 3, 4], 2)); // 输出:[[1, 2], [3, 4]]
7 测试与调试
- 将代码 分解为 小模块,有助于进行 单元测试 和 调试。
- 可以针对 每个模块 独立编写 测试用例,提高 测试 覆盖率。
// 示例代码 11
// 单独测试工具模块:
// mathUtils.test.js
import { add } from './mathUtils.js';
test('add function', () => {
expect(add(2, 3)).toBe(5);
});
4 Set / Map
Set 和 Map 是 ES6 引入的 两种 新 数据结构,分别用于 存储 唯一值 的 集合 和 键值对 的 映射关系。
Set 和 Map 的操作(如 查找、插入、删除)在多数情况下 比 普通对象 和 数组 更快,尤其是当 数据量 很大时。
4.1 Set
Set 是一个 集合,它存储的是 唯一值。它可以是 任何类型 的值(数字、字符串、对象等)。
// 示例代码 6
const mySet = new Set([1, 2, 3, 3, 4]);
console.log(mySet); // 输出:Set(4) { 1, 2, 3, 4 }
// 遍历 Set
for (let value of mySet) {
console.log(value); // 输出:1, 2, 3
}
mySet.forEach(value => console.log(value)); // 输出:1, 2, 3
Set 和 数组 转换
// 示例代码 7
// 数组 转 Set
const arr = [1, 2, 2, 3];
const mySet = new Set(arr); // 去重
console.log([...mySet]); // 输出:[1, 2, 3]
// Set 转 数组
const mySet = new Set([1, 2, 3]);
const arr = Array.from(mySet);
console.log(arr); // 输出:[1, 2, 3]
4.2 Map
Map 是一种** 键值对 集合**,其中 键 可以是 任意数据类型。与 普通对象 不同,Map 保留 键值对 的 插入顺序。
// 示例代码 8
const myMap = new Map();
myMap.set('name', 'Alice'); // 设置键值对
myMap.set('age', 25); // 设置键值对
// 遍历 Map
for (let [key, value] of myMap) {
console.log(`${key}: ${value}`); // 输出:name: Alice, age: 25
}
myMap.forEach((value, key) => console.log(`${key}: ${value}`));
// 输出:name: Alice, age: 25
Map 和 对象 转换
// 示例代码 9
// 对象 转 Map
const obj = { name: 'Alice', age: 25 };
const myMap = new Map(Object.entries(obj));
console.log(myMap); // 输出:Map(2) { 'name' => 'Alice', 'age' => 25 }
// Map 转 对象
const myMap = new Map([['name', 'Alice'], ['age', 25]]);
const obj = Object.fromEntries(myMap);
console.log(obj); // 输出:{ name: 'Alice', age: 25 }
5 Class 语法(Class Syntax)
提供了更接近 传统 面向对象编程 的 类 和 继承 语法。
// 示例代码 10
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
class Student extends Person {
constructor(name, grade) {
super(name);
this.grade = grade;
}
}