
ECMAScript 2015(简称ES6)是JavaScript语言的重大更新,引入了许多新特性,使JavaScript更加强大、灵活和现代化。 这些新特性不仅提升了开发效率,还改善了代码的可读性和可维护性。本文将深入解析ES6的核心特性, 包括箭头函数、类声明、模块化、解构赋值等,并通过实际示例展示如何应用这些特性。 无论您是JavaScript新手还是经验丰富的开发者,都能从中获得实用的知识和技巧。
1. 块级作用域与 let/const
ES6引入了块级作用域,通过let和const关键字声明变量,解决了var声明变量带来的作用域问题。
// let 声明块级作用域变量
{
let x = 10;
console.log(x); // 10
}
console.log(x); // ReferenceError
// const 声明常量
const PI = 3.14159;
PI = 3.14; // TypeError: Assignment to constant variable
// var vs let 在循环中的区别
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 输出 3, 3, 3
}
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 100); // 输出 0, 1, 2
}
{
let x = 10;
console.log(x); // 10
}
console.log(x); // ReferenceError
// const 声明常量
const PI = 3.14159;
PI = 3.14; // TypeError: Assignment to constant variable
// var vs let 在循环中的区别
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 输出 3, 3, 3
}
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 100); // 输出 0, 1, 2
}
// 输出结果:
10
ReferenceError: x is not defined
3
3
3
0
1
2
主要优势
- 避免变量提升带来的问题
- 防止意外覆盖全局变量
- 使循环中的变量作用域更加合理
- const确保重要值不会被意外修改
2. 箭头函数
箭头函数提供了更简洁的函数语法,并且自动绑定当前上下文的this值。
// 传统函数表达式
const sum = function(a, b) {
return a + b;
};
// 箭头函数
const sum = (a, b) => a + b;
// 单参数可省略括号
const square = n => n * n;
// this 绑定示例
function Counter() {
this.count = 0;
setInterval(() => {
this.count++; // this 指向 Counter 实例
console.log(this.count);
}, 1000);
}
const counter = new Counter();
const sum = function(a, b) {
return a + b;
};
// 箭头函数
const sum = (a, b) => a + b;
// 单参数可省略括号
const square = n => n * n;
// this 绑定示例
function Counter() {
this.count = 0;
setInterval(() => {
this.count++; // this 指向 Counter 实例
console.log(this.count);
}, 1000);
}
const counter = new Counter();
// 箭头函数使用场景:
1. 数组方法回调
2. 需要绑定当前上下文的函数
3. 简洁的单行函数
// 注意事项:
- 没有自己的this、arguments、super
- 不能用作构造函数
- 没有prototype属性
3. 解构赋值
解构赋值允许从数组或对象中提取值并赋值给变量,大大简化了代码。
// 数组解构
const numbers = [1, 2, 3];
const [a, b, c] = numbers;
console.log(a, b, c); // 1, 2, 3
// 对象解构
const user = {
name: 'John',
age: 30,
email: 'john@example.com'
};
const { name, email } = user;
console.log(name, email); // John, john@example.com
// 函数参数解构
function getUserInfo({ name, age }) {
return `${name} is ${age} years old`;
}
console.log(getUserInfo(user)); // John is 30 years old
const numbers = [1, 2, 3];
const [a, b, c] = numbers;
console.log(a, b, c); // 1, 2, 3
// 对象解构
const user = {
name: 'John',
age: 30,
email: 'john@example.com'
};
const { name, email } = user;
console.log(name, email); // John, john@example.com
// 函数参数解构
function getUserInfo({ name, age }) {
return `${name} is ${age} years old`;
}
console.log(getUserInfo(user)); // John is 30 years old
// 解构赋值的高级用法:
// 默认值
const { role = 'user' } = user;
// 重命名
const { name: userName } = user;
// 嵌套解构
const { address: { city } } = user;
// 剩余操作符
const [first, ...rest] = [1, 2, 3, 4];
4. 模板字符串
模板字符串使用反引号(`)定义,支持多行字符串和嵌入表达式。
const name = 'John';
const age = 30;
// 传统字符串拼接
const greeting = 'Hello, my name is ' + name + ' and I am ' + age + ' years old.';
// 模板字符串
const greeting = `Hello, my name is ${name} and I am ${age} years old.`;
// 多行字符串
const message = `
Dear ${name},
Thank you for your interest in our product.
We will contact you shortly.
Best regards,
The Team
`;
// 表达式计算
const total = `Total: $${(25 * 1.2).toFixed(2)}`;
const age = 30;
// 传统字符串拼接
const greeting = 'Hello, my name is ' + name + ' and I am ' + age + ' years old.';
// 模板字符串
const greeting = `Hello, my name is ${name} and I am ${age} years old.`;
// 多行字符串
const message = `
Dear ${name},
Thank you for your interest in our product.
We will contact you shortly.
Best regards,
The Team
`;
// 表达式计算
const total = `Total: $${(25 * 1.2).toFixed(2)}`;
// 模板字符串输出:
Hello, my name is John and I am 30 years old.
Dear John,
Thank you for your interest in our product.
We will contact you shortly.
Best regards,
The Team
Total: $30.00
5. 类与继承
ES6引入了class关键字,提供更清晰、更面向对象的语法来创建构造函数和继承。
// 类定义
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
// 静态方法
static info() {
console.log('This is a Person class');
}
}
// 继承
class Student extends Person {
constructor(name, age, major) {
super(name, age);
this.major = major;
}
study() {
console.log(`${this.name} is studying ${this.major}`);
}
}
// 使用类
const john = new Person('John', 30);
john.greet();
const alice = new Student('Alice', 20, 'Computer Science');
alice.greet();
alice.study();
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
// 静态方法
static info() {
console.log('This is a Person class');
}
}
// 继承
class Student extends Person {
constructor(name, age, major) {
super(name, age);
this.major = major;
}
study() {
console.log(`${this.name} is studying ${this.major}`);
}
}
// 使用类
const john = new Person('John', 30);
john.greet();
const alice = new Student('Alice', 20, 'Computer Science');
alice.greet();
alice.study();
// 输出结果:
Hello, my name is John
Hello, my name is Alice
Alice is studying Computer Science
类特性总结
- constructor方法用于初始化对象
- extends关键字实现继承
- super调用父类构造函数和方法
- static关键字定义静态方法
- getter和setter方法
6. Promise与异步处理
Promise提供了一种更优雅的方式处理异步操作,避免了回调地狱。
// 创建Promise
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { id: 1, name: 'John' };
resolve(data); // 成功
// reject('Error: Data not available'); // 失败
}, 1000);
});
};
// 使用Promise
fetchData()
.then(data => {
console.log('Data received:', data);
return data.name;
})
.then(name => {
console.log('User name:', name);
})
.catch(error => {
console.error('Error:', error);
});
// Promise.all 并行处理
Promise.all([
fetchData(),
Promise.resolve('Additional data')
])
.then(([data1, data2]) => {
console.log('All data:', data1, data2);
});
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { id: 1, name: 'John' };
resolve(data); // 成功
// reject('Error: Data not available'); // 失败
}, 1000);
});
};
// 使用Promise
fetchData()
.then(data => {
console.log('Data received:', data);
return data.name;
})
.then(name => {
console.log('User name:', name);
})
.catch(error => {
console.error('Error:', error);
});
// Promise.all 并行处理
Promise.all([
fetchData(),
Promise.resolve('Additional data')
])
.then(([data1, data2]) => {
console.log('All data:', data1, data2);
});
// 输出结果:
Data received: {id: 1, name: "John"}
User name: John
All data: {id: 1, name: "John"} "Additional data"
7. 模块化
ES6模块化允许将代码拆分为多个文件,并通过export和import进行管理。
// math.js - 导出模块
export const PI = 3.14159;
export function sum(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
// app.js - 导入模块
import multiply, { PI, sum } from './math.js';
console.log(PI); // 3.14159
console.log(sum(2, 3)); // 5
console.log(multiply(4, 5)); // 20
// 重命名导入
import { sum as add } from './math.js';
console.log(add(10, 20)); // 30
// 导入所有命名导出
import * as math from './math.js';
console.log(math.PI);
console.log(math.sum(5, 7));
export const PI = 3.14159;
export function sum(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
// app.js - 导入模块
import multiply, { PI, sum } from './math.js';
console.log(PI); // 3.14159
console.log(sum(2, 3)); // 5
console.log(multiply(4, 5)); // 20
// 重命名导入
import { sum as add } from './math.js';
console.log(add(10, 20)); // 30
// 导入所有命名导出
import * as math from './math.js';
console.log(math.PI);
console.log(math.sum(5, 7));
// 模块化的优势:
1. 避免全局命名空间污染
2. 代码组织更清晰
3. 依赖关系明确
4. 按需加载
5. 提高代码复用性
// 注意事项:
- 需要现代浏览器或打包工具支持
- 严格模式自动启用
- 顶层this为undefined
8. 其他实用特性
ES6还引入了许多其他实用特性,极大提升了开发体验。
// 默认参数
function greet(name = 'Guest') {
console.log(`Hello, ${name}!`);
}
greet(); // Hello, Guest!
// 剩余参数
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
// 扩展运算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// 对象字面量增强
const name = 'John';
const age = 30;
const user = { name, age }; // { name: 'John', age: 30 }
// Symbol类型
const id = Symbol('id');
const user = {
[id]: 123,
name: 'John'
};
console.log(user[id]); // 123
function greet(name = 'Guest') {
console.log(`Hello, ${name}!`);
}
greet(); // Hello, Guest!
// 剩余参数
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
// 扩展运算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// 对象字面量增强
const name = 'John';
const age = 30;
const user = { name, age }; // { name: 'John', age: 30 }
// Symbol类型
const id = Symbol('id');
const user = {
[id]: 123,
name: 'John'
};
console.log(user[id]); // 123
// ES6新增数据类型:
- Symbol: 唯一标识符
// 新增数据结构:
- Map: 键值对集合
- Set: 唯一值集合
- WeakMap: 弱引用Map
- WeakSet: 弱引用Set
// 新增对象方法:
Object.assign()
Object.is()
Object.keys()
Object.values()
Object.entries()