ES6 新特性
ES6(ECMAScript 2015)是 JavaScript 语言的一个重要更新,引入了许多新特性和语法改进,使 JavaScript 更加强大和易用。这些新特性大大提升了开发体验和代码质量。
let 和 const
ES6 引入了两个新的变量声明关键字:let 和 const,它们提供了块级作用域。
javascript
// var 的函数作用域
function varExample() {
if (true) {
var x = 1;
}
console.log(x); // 1 (可以访问)
}
// let 的块级作用域
function letExample() {
if (true) {
let y = 1;
}
// console.log(y); // ReferenceError: y is not defined
}
// const 声明常量
const PI = 3.14159;
// PI = 3.14; // TypeError: Assignment to constant variable
// const 对象和数组
const person = { name: "张三" };
person.name = "李四"; // 可以修改属性
person.age = 25; // 可以添加属性
// person = {}; // TypeError: Assignment to constant variable
const numbers = [1, 2, 3];
numbers.push(4); // 可以修改数组内容
// numbers = [5, 6, 7]; // TypeError: Assignment to constant variable模板字符串
模板字符串使用反引号(`)包围,支持多行字符串和字符串插值。
javascript
// 基本用法
let name = "张三";
let greeting = `你好,${name}!`;
console.log(greeting); // "你好,张三!"
// 多行字符串
let multiline = `
这是第一行
这是第二行
这是第三行
`;
// 表达式插值
let a = 5;
let b = 10;
console.log(`a + b = ${a + b}`); // "a + b = 15"
// 嵌套模板字符串
let users = [
{ name: "张三", age: 25 },
{ name: "李四", age: 30 }
];
let userList = `
<ul>
${users.map(user => `<li>${user.name} (${user.age}岁)</li>`).join('\n ')}
</ul>
`;解构赋值
解构赋值允许我们从数组或对象中提取值并赋给变量。
javascript
// 数组解构
let [first, second, third] = [1, 2, 3];
console.log(first); // 1
console.log(second); // 2
console.log(third); // 3
// 跳过某些值
let [a, , c] = [1, 2, 3];
console.log(a); // 1
console.log(c); // 3
// 默认值
let [x = 10, y = 20] = [5];
console.log(x); // 5
console.log(y); // 20
// 对象解构
let person = { name: "张三", age: 25, city: "北京" };
let { name, age } = person;
console.log(name); // "张三"
console.log(age); // 25
// 重命名变量
let { name: fullName, age: years } = person;
console.log(fullName); // "张三"
console.log(years); // 25
// 默认值
let { name: n, job = "开发者" } = person;
console.log(n); // "张三"
console.log(job); // "开发者"
// 嵌套解构
let student = {
name: "李四",
address: {
city: "上海",
district: "浦东新区"
}
};
let { address: { city } } = student;
console.log(city); // "上海"扩展运算符
扩展运算符(...)允许我们在函数调用/数组构造时将数组表达式或字符串在语法层面展开。
javascript
// 数组展开
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]
// 复制数组
let original = [1, 2, 3];
let copy = [...original];
console.log(copy); // [1, 2, 3]
copy.push(4);
console.log(original); // [1, 2, 3] (原数组未改变)
console.log(copy); // [1, 2, 3, 4]
// 字符串展开
let str = "hello";
let chars = [...str];
console.log(chars); // ['h', 'e', 'l', 'l', 'o']
// 对象展开(ES2018)
let obj1 = { a: 1, b: 2 };
let obj2 = { c: 3, d: 4 };
let merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 2, c: 3, d: 4 }
// 复制对象
let originalObj = { name: "张三", age: 25 };
let copyObj = { ...originalObj };
console.log(copyObj); // { name: "张三", age: 25 }
// 合并对象并覆盖属性
let defaults = { theme: "light", lang: "zh" };
let userPrefs = { lang: "en", notifications: true };
let settings = { ...defaults, ...userPrefs };
console.log(settings); // { theme: "light", lang: "en", notifications: true }箭头函数
箭头函数提供了一种更简洁的函数书写方式,并且不绑定自己的 this。
javascript
// 基本语法
let add = (a, b) => a + b;
console.log(add(2, 3)); // 5
// 单参数可以省略括号
let double = x => x * 2;
console.log(double(5)); // 10
// 多行函数体需要大括号和 return
let multiply = (a, b) => {
let result = a * b;
return result;
};
console.log(multiply(3, 4)); // 12
// 无参数
let greet = () => "Hello!";
console.log(greet()); // "Hello!"
// 返回对象字面量需要加括号
let createUser = (name, age) => ({ name, age });
console.log(createUser("张三", 25)); // { name: "张三", age: 25 }
// 箭头函数中的 this
let obj = {
name: "对象",
regularFunction: function() {
console.log("常规函数:", this.name);
// 箭头函数继承外层的 this
let arrow = () => {
console.log("箭头函数:", this.name);
};
arrow();
}
};
obj.regularFunction();
// 输出:
// 常规函数: 对象
// 箭头函数: 对象类(Class)
ES6 引入了类语法,提供了一种更清晰的面向对象编程方式。
javascript
// 基本类定义
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `你好,我是 ${this.name},今年 ${this.age} 岁。`;
}
// 静态方法
static getSpecies() {
return "人类";
}
}
let person = new Person("张三", 25);
console.log(person.greet()); // "你好,我是 张三,今年 25 岁。"
console.log(Person.getSpecies()); // "人类"
// 类继承
class Student extends Person {
constructor(name, age, school) {
super(name, age); // 调用父类构造函数
this.school = school;
}
// 方法重写
greet() {
return `${super.greet()} 我在 ${this.school} 学习。`;
}
study() {
return `${this.name} 正在学习。`;
}
}
let student = new Student("李四", 20, "北京大学");
console.log(student.greet()); // "你好,我是 李四,今年 20 岁。 我在 北京大学 学习。"
console.log(student.study()); // "李四 正在学习。"
// Getter 和 Setter
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
get area() {
return this.width * this.height;
}
set area(value) {
// 这里简化处理,实际可能需要更复杂的逻辑
this.width = Math.sqrt(value);
this.height = Math.sqrt(value);
}
}
let rect = new Rectangle(5, 3);
console.log(rect.area); // 15
rect.area = 25;
console.log(rect.width); // 5
console.log(rect.height); // 5模块(Modules)
ES6 引入了模块系统,允许我们将代码组织成独立的模块。
javascript
// math.js - 导出模块
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// 默认导出
export default function subtract(a, b) {
return a - b;
}
// 可以在文件末尾统一导出
export { add as sum, multiply as product };
// main.js - 导入模块
import subtract, { PI, add, multiply as mul, sum } from './math.js';
console.log(PI); // 3.14159
console.log(add(2, 3)); // 5
console.log(mul(2, 3)); // 6
console.log(subtract(5, 2)); // 3Promise
Promise 提供了更好的异步编程方式。
javascript
// 创建 Promise
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
let success = true;
if (success) {
resolve("操作成功!");
} else {
reject("操作失败!");
}
}, 1000);
});
// 使用 Promise
promise
.then(result => {
console.log(result); // "操作成功!"
})
.catch(error => {
console.error(error); // "操作失败!"
});
// Promise 静态方法
Promise.all([
fetch('/api/data1'),
fetch('/api/data2')
]).then(responses => {
console.log("所有请求完成");
});
Promise.race([
fetch('/api/data1'),
fetch('/api/data2')
]).then(response => {
console.log("第一个完成的请求");
});其他有用特性
默认参数
javascript
function greet(name = "朋友", greeting = "你好") {
return `${greeting},${name}!`;
}
console.log(greet()); // "你好,朋友!"
console.log(greet("张三")); // "你好,张三!"
console.log(greet("李四", "欢迎")); // "欢迎,李四!"剩余参数
javascript
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
// 与解构赋值结合使用
let [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [2, 3, 4, 5]for...of 循环
javascript
let fruits = ["苹果", "香蕉", "橙子"];
// 遍历数组元素
for (let fruit of fruits) {
console.log(fruit);
}
// 遍历字符串
let str = "hello";
for (let char of str) {
console.log(char);
}
// 遍历 Map
let map = new Map([["a", 1], ["b", 2]]);
for (let [key, value] of map) {
console.log(key, value);
}ES6 的这些新特性使 JavaScript 更加强大和易用,提升了代码的可读性和可维护性。掌握这些特性对于现代 JavaScript 开发至关重要。