2190 字
11 分钟
ES6+ 新特性完整教程(解构赋值、展开运算符、模块化)

ES6+ 新特性完整教程(解构赋值、展开运算符、模块化)#

上一篇我们学会了 JavaScript 基础语法。但你在网上看到的现代 JS 代码,很多写法你可能没见过——那些大多是 ES6+(ES2015 及以后版本) 带来的新特性。这一篇就专门讲这些现代写法,全部配有示例,照着敲就能懂。


一、什么是 ES6?#

ES 是 ECMAScript 的缩写,它是一份”JavaScript 语言标准说明书”。每隔一两年,标准就会更新,加入新语法。ES6(也叫 ES2015)是 2015 年发布的一次大更新,从那以后的版本统称 ES6+

为什么要学? 现在所有主流浏览器都支持 ES6+,而且几乎所有现代框架(Vue、React)都在用它。不学 ES6+,你会看不懂真实项目的代码。


二、解构赋值:从数组/对象里”拆”出值#

以前我们想从数组里取值,要一个个按下标拿:

let arr = ["小明", 18, "高三"];
let name = arr[0];
let age = arr[1];
console.log(name, age); // 小明 18

解构赋值可以一行搞定:把数组”拆开”,按顺序赋给变量。

let arr = ["小明", 18, "高三"];
let [name, age, grade] = arr;
console.log(name); // 小明
console.log(age); // 18
console.log(grade); // 高三

let [a, b, c] = 数组 的意思是:把数组的第 0 个元素给 a,第 1 个给 b,第 2 个给 c。

跳过某些元素#

let arr = ["a", "b", "c", "d"];
let [first, , third] = arr; // 中间空着就是跳过
console.log(first); // a
console.log(third); // c

给默认值(防止 undefined)#

let arr = ["苹果"];
let [fruit, price = "未知"] = arr;
console.log(fruit); // 苹果
console.log(price); // 未知(因为数组里没有第二个元素)

对象解构(最常用!)#

对象解构不用管顺序,按属性名取值:

let student = { name: "小红", age: 20, city: "北京" };
let { name, age } = student;
console.log(name); // 小红
console.log(age); // 20

还可以改名和给默认值:

let { name: studentName, city = "未知", score = 0 } = student;
console.log(studentName); // 小红
console.log(city); // 北京(原对象里有)
console.log(score); // 0(原对象没有,用默认值)

函数参数解构(实战高频写法)#

写函数时,直接解构参数对象,调用的人一眼就能看清传了什么:

function greet({ name, age }) {
console.log(`你好,我叫${name},今年${age}岁`);
}
greet({ name: "小刚", age: 25 }); // 你好,我叫小刚,今年25岁

交换两个变量的值(一行搞定)#

以前要三行加临时变量,现在:

let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1

三、展开运算符:把数组/对象”摊开”#

展开运算符是三个点 ...,作用是把数组或对象”展开”成一个个元素。

展开数组#

let arr1 = [1, 2, 3];
let arr2 = [4, 5];
let all = [...arr1, ...arr2];
console.log(all); // [1, 2, 3, 4, 5]

这比 concat 拼接更直观,还能在中间插值:

let all = [0, ...arr1, 9];
console.log(all); // [0, 1, 2, 3, 9]

复制数组(避免”引用”坑)#

重要知识点: 直接 let b = a 并不会复制数组,a 和 b 指向同一个数组,改 b 会连累 a:

let a = [1, 2, 3];
let b = a;
b.push(4);
console.log(a); // [1, 2, 3, 4] !a 也被改了

用展开运算符才能真正复制:

let a = [1, 2, 3];
let b = [...a];
b.push(4);
console.log(a); // [1, 2, 3](a 没变)
console.log(b); // [1, 2, 3, 4]

展开对象#

let user = { name: "小明", age: 18 };
let info = { ...user, city: "北京" };
console.log(info);
// { name: "小明", age: 18, city: "北京" }

注意顺序: 后面的会覆盖前面的同名属性:

let user = { name: "小明", age: 18 };
let admin = { ...user, age: 30 };
console.log(admin.age); // 30(后面的 age 覆盖了前面的)

把类数组转成真数组#

比如 arguments、DOM 集合(NodeList)不是真数组,不能直接用 map。用展开可以转:

function collect() {
let arr = [...arguments];
console.log(Array.isArray(arr)); // true
}
collect(1, 2, 3);

四、剩余参数:把”剩下的”收集成数组#

剩余参数也是 ...,但用在函数参数里,表示”把没被命名的参数收进一个数组”。注意和展开运算符的区别:展开是”摊开”,剩余是”收集”。

function sum(...nums) {
let total = 0;
for (let n of nums) {
total += n;
}
return total;
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15

不管传几个参数,都会被收进 nums 数组里。

固定参数 + 剩余参数结合:

function introduce(name, ...hobbies) {
console.log(`${name} 的爱好:${hobbies.join("、")}`);
}
introduce("小明", "篮球", "编程", "画画");
// 小明 的爱好:篮球、编程、画画

五、箭头函数:更简洁的函数写法#

上一篇已经简单介绍过,这里再深入一点。

// 传统写法
function add(a, b) {
return a + b;
}
// 箭头函数
const add = (a, b) => a + b;

几个简化规则:

// 1. 只有一个参数,可以省略括号
const double = n => n * 2;
console.log(double(5)); // 10
// 2. 没有参数,必须写空括号
const sayHi = () => console.log("你好");
sayHi();
// 3. 函数体多行,要加大括号和 return
const calc = (a, b) => {
let sum = a + b;
return sum * 2;
};
console.log(calc(3, 4)); // 14

箭头函数和 this: 这是新手最容易懵的点。传统函数里的 this 会随调用方式变化,箭头函数里的 this 固定指向”定义它的地方”。现在你只需记住:在回调函数(比如 addEventListener 里)用箭头函数,this 的行为更符合直觉


六、模块化:import / export#

为什么需要模块?#

一个项目代码多了,全写在一个文件里会:变量互相冲突、找不到哪段代码在哪、不好复用。模块就是”把一个文件当成一个独立的小盒子,只把需要的东西导出给别人用”。

导出:export#

假设有两个文件:math.jsmain.js

math.js(导出的一方):

// 命名导出:可以导多个
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}

导入:import#

main.js(使用的一方):

// 命名导入:名字必须和导出的一致,用花括号
import { add, multiply, PI } from "./math.js";
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
console.log(PI); // 3.14159

默认导出:export default#

每个模块只能有一个默认导出,导入时不用花括号、可以随便起名:

math.js
export default function subtract(a, b) {
return a - b;
}
main.js
import subtract from "./math.js";
console.log(subtract(10, 4)); // 6

导入时改名:as#

import { add as plus } from "./math.js";
console.log(plus(1, 2)); // 3

混合导入#

import subtract, { add, PI } from "./math.js";

一次性导入全部:*#

import * as math from "./math.js";
console.log(math.add(1, 2));
console.log(math.PI);

怎么在浏览器里用?#

在 HTML 里给 script 标签加 type="module"

<script type="module" src="main.js"></script>

浏览器看到 import 语句,会自动加载对应的模块文件。注意:用模块方式打开页面,必须通过本地服务器(如 python -m http.server)访问,直接双击 HTML 文件会因为浏览器安全策略报错。


七、其他实用新特性速览#

这些特性看一眼就能用,都非常实用:

1. 可选链 ?.(避免”读不到属性”报错)#

let user = { name: "小明", address: { city: "北京" } };
// 以前:要一层层判断
if (user && user.address && user.address.city) {
console.log(user.address.city);
}
// 现在:?. 会自动检查,没有就返回 undefined,不报错
console.log(user?.address?.city); // 北京
console.log(user?.phone?.number); // undefined(不会报错)

2. 空值合并 ??(给默认值的另一种方式)#

let a = null;
let b = "有值";
console.log(a ?? "默认值"); // 默认值(null 或 undefined 时用默认)
console.log(b ?? "默认值"); // 有值
// 和 || 的区别:|| 对 0、空字符串 也会取右边
console.log(0 || "默认"); // 默认
console.log(0 ?? "默认"); // 0 !(?? 只在 null/undefined 时取默认)

3. 字符串 startsWith / includes#

let str = "Hello World";
console.log(str.startsWith("Hello")); // true
console.log(str.endsWith("World")); // true
console.log(str.includes("o W")); // true
console.log("abc".repeat(3)); // abcabcabc

4. 数组 find / findIndex#

let students = [
{ name: "小明", score: 95 },
{ name: "小红", score: 88 }
];
let found = students.find(s => s.name === "小红");
console.log(found.score); // 88
let index = students.findIndex(s => s.score < 90);
console.log(index); // 1(小红的位置)

5. class 类(面向对象语法糖)#

class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} 叫了一声`);
}
}
let dog = new Animal("旺财");
dog.speak(); // 旺财 叫了一声

八、总结#

这一篇我们学会了 ES6+ 最核心的现代写法:

  • 解构赋值:从数组 [a, b] 和对象 {a, b} 里快速取值
  • 展开运算符 ...:摊开数组/对象,用于合并、复制
  • 剩余参数:把剩余参数收进数组
  • 箭头函数:更简洁的函数写法
  • 模块化:export 导出、import 导入,组织大型代码
  • 实用新特性:可选链 ?.、空值合并 ??、find、class 等

这些语法单独看都很简单,但组合起来就是现代 JS 项目的地基。下一篇我们学习异步编程——这是处理”等待”(比如网络请求)的关键。

ES6+ 新特性完整教程(解构赋值、展开运算符、模块化)
https://021028.xyz/posts/default/67/
作者
021028
发布于
2026-08-11
许可协议
CC BY-NC-SA 4.0