ES6的新特性

3 阅读4分钟

ES6(即 ECMAScript 2015)是 JavaScript 发展史上一个里程碑式的版本,它让这门语言从简单的“脚本工具”正式迈向了适合大型项目开发的“现代编程语言”。

我将其核心新特性分为基础语法、函数增强、数据结构与集合、异步与模块化四大类,来进行讲解:

基础语法升级

1. letconst 声明 解决了 var 变量提升和作用域混乱的问题,引入了块级作用域的概念。

  • let:声明块级变量,不存在变量提升,不能重复声明。
  • const:声明常量,必须初始化,且声明后不能重新赋值(引用类型可修改内部属性)。
if (true) {
  let a = 10;
  const PI = 3.14;
  // a 和 PI 仅在 if 块内有效
}
// console.log(a); // 报错:ReferenceError

2. 模板字符串 (Template Literals) 使用反引号 (`) 定义字符串,支持直接换行和 ${} 插值,彻底告别繁琐的字符串拼接。

const name = "前端开发";
const str = `你好,我是${name},
这是多行字符串示例。`;

3. 解构赋值 (Destructuring) 允许从数组或对象中快速提取值并赋给变量,语法非常优雅。

// 数组解构
const [a, b] = ;[[source_group_web_5]]

// 对象解构(支持重命名和默认值)
const { name: userName, age = 18 } = { name: 'Alice' };

4. 展开运算符与 Rest 参数 (...)

  • 展开 (Spread):将数组或对象展开。常用于数组/对象合并、浅拷贝。
  • Rest 参数:将函数的多个剩余参数收集为一个数组。
// 展开运算符合并数组
const arr1 = ;
const arr2 = [...arr1, 3, 4]; //[[source_group_web_7]]

// Rest 参数收集函数参数
function sum(...nums) {
  return nums.reduce((a, b) => a + b);
}
sum(1, 2, 3); // 6

函数增强

1. 箭头函数 (Arrow Functions) 提供了更简洁的函数写法,并且没有自己的 this,它的 this 继承自外层作用域。非常适合用于回调函数。

// 简洁写法
const add = (a, b) => a + b;

// 解决传统函数 this 指向问题
const obj = {
  name: "Test",
  sayHi: () => console.log(this.name), // 这里的 this 指向定义时的外层(通常是全局)
};

2. 函数参数默认值 可以直接在函数定义时给参数设置默认值,增强了代码的健壮性。

function greet(name = "Guest") {
  return `Hi, ${name}`;
}

数据结构与集合

1. 新增 MapSet

  • Set:类似于数组,但成员的值都是唯一的,常用于数组去重。
  • Map:类似于对象,但“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const set = new Set(); // Set {1, 2, 3}
const map = new Map();
map.set("name", "Alice");

2. 数组和对象的扩展方法

  • 数组:新增了 find()(查找第一个符合条件的元素)、findIndex()includes() 等实用方法。
  • 对象Object.assign() 用于合并对象,Object.keys() / Object.values() 用于快速获取键值。

异步与模块化(工程化基石)

1. 原生模块化 (ES Modules) ES6 首次引入了官方的模块化方案,使用 importexport,让前端代码的组织更加规范和清晰(这也是现代前端框架和 Vite 等工具的基础)。

// 导出
export const name = "ES6";
export function hello() {}

// 导入
import { name, hello } from "./module.js";

2. Promise 与异步编程 Promise 是 ES6 中解决“回调地狱”的核心方案,它让异步操作可以像同步代码一样通过链式调用(.then())来处理。配合后续的 async/await 语法,彻底改变了 JavaScript 的异步编程体验。

new Promise((resolve, reject) => {
  // 异步操作
  resolve("成功");
}).then((data) => {
  console.log(data);
});

补充 类的新特性

ES6 引入的 class(类)是 JavaScript 面向对象编程的一个里程碑。它并不是创造了一种全新的底层机制,而是对原有基于原型(prototype-based)继承模型的一种语法糖,让代码的写法更接近传统的面向对象语言(如 Java、C++),从而大幅提升了代码的可读性和可维护性。

以下是 ES6 类(class)的核心新特性与关键点:

核心语法与结构

1. class 关键字与 constructor 构造函数 使用 class 关键字来定义一个类,类体中包含一个特殊的 constructor 方法,用于在实例化对象时初始化属性。

class Person {
  // 构造函数:实例化时自动调用
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
const p = new Person('张三', 25);

2. 实例方法定义更简洁 在类体中直接定义方法,不需要使用 function 关键字,方法之间也不需要用逗号分隔。这些方法会被自动挂载到类的原型(prototype)上,供所有实例共享。

class Person {
  constructor(name) { this.name = name; }
  // 实例方法
  sayHello() {
    console.log(`你好,我是${this.name}`);
  }
}

3. 静态方法 (static) 使用 static 关键字定义静态方法。静态方法属于类本身,不能通过实例调用,只能通过类名直接调用。常用于工具函数或工厂方法。

class MathUtil {
  static add(a, b) {
    return a + b;
  }
}
console.log(MathUtil.add(1, 2)); // 3
// new MathUtil().add(1, 2); // 报错:实例无法调用静态方法

4. 存取器属性 (gettersetter) 通过 getset 关键字,可以在读取或设置属性时进行拦截,非常适合用来做数据校验或计算属性。

class User {
  constructor(name) { this._name = name; }
  get name() { return this._name.toUpperCase(); } // 读取时转换大写
  set name(newName) { // 设置时进行校验
    if (newName.length < 2) throw new Error('名字太短了');
    this._name = newName;
  }
}

继承机制 (extendssuper)

1. extends 关键字实现继承 ES6 提供了非常直观的 extends 关键字来实现类的继承,彻底告别了 ES5 中繁琐且容易出错的原型链赋值。

2. super 关键字 在子类的构造函数中,必须先调用 super()(即父类的构造函数),然后才能使用 this 关键字。在普通方法中,super.method() 可以用来调用父类原型上的方法。

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age); // 调用父类构造函数,初始化 name 和 age
    this.grade = grade;
  }
  sayHello() {
    super.sayHello(); // 调用父类的 sayHello 方法
    console.log(`我上${this.grade}年级`);
  }
}

关键特性与注意事项

1. 本质是“语法糖”,底层依然是原型 尽管写法变了,但 class 的底层依然是基于原型的。typeof Person 的结果依然是 'function',类的所有实例方法依然定义在 Person.prototype 上。

2. 不存在变量提升 (Hoisting) 与 ES5 的函数声明不同,类声明不会被提升。你必须先声明类,然后才能使用它(即 new 一个实例),否则会抛出 ReferenceError

3. 默认开启严格模式 在类的内部(包括类体中的所有代码),默认就是严格模式('use strict'),这能有效避免一些不规范的 JS 写法带来的隐患。

4. 方法默认不可枚举 在 ES5 中,挂载到原型上的方法默认是可以被 for...in 遍历出来的(可枚举)。而 ES6 的 class 内部定义的方法,默认是不可枚举的,这让对象属性的遍历更加干净。


进阶特性(ES2022+ 现代补充)

随着标准的不断演进,现代 JavaScript 的类还增加了以下实用特性:

  • 实例属性的简洁声明:可以直接在类顶层声明属性并赋初始值,无需写在 constructor 里(如 count = 0;)。
  • 私有属性与方法 (#):在属性或方法名前加上 # 前缀(如 #secretData),就可以将其限制为仅在类内部访问,外部无法读取或修改,真正实现了私有化。

掌握这些特性,你就能在现代前端框架(如 React 的类组件)或复杂的业务逻辑封装中,写出结构清晰、健壮且易于维护的面向对象代码。