JS 入门通关手册(27):ES6+ 高频新特性:解构、展开、模板字符串、可选链
上一篇我们吃透了数组高阶函数,代码变得简洁优雅。这一篇聚焦ES6+ 最常用的新特性—— 这些特性不是 “花里胡哨” 的语法,而是日常开发中能直接提升效率、减少冗余代码的核心工具,也是面试高频考点。
本文全程贴合前 6 篇风格,无多余格式,直接适配聊天窗口查看,重点讲解解构赋值、展开运算符、模板字符串、可选链等 8 个高频特性,所有代码可直接复制运行,兼顾入门和实战。
一、解构赋值:快速提取数据(最常用)
解构赋值是 “快速从数组 / 对象中提取值,赋值给变量” 的语法糖,替代繁琐的arr[0]、obj.key写法,让代码更简洁。
1. 数组解构(按位置提取)
javascript
运行
// 基础用法 const arr = [10, 20, 30]; const [a, b, c] = arr; // 按位置解构 console.log(a, b, c); // 10 20 30 // 跳过某一项 const [x, , z] = arr; // 跳过第二项 console.log(x, z); // 10 30 // 剩余参数(...):提取剩余所有项 const [first, ...rest] = arr; console.log(first); // 10 console.log(rest); // [20, 30] // 默认值:解构不到时用默认值 const [m, n, p, q = 40] = arr; console.log(q); // 40(arr 只有3项,q 用默认值) // 实战:交换两个变量(无需临时变量) let num1 = 1, num2 = 2; [num1, num2] = [num2, num1]; console.log(num1, num2); // 2 12. 对象解构(按键名提取)
javascript
运行
// 基础用法(键名必须匹配) const user = { name: "张三", age: 20, gender: "男" }; const { name, age } = user; // 按键名解构 console.log(name, age); // 张三 20 // 重命名:避免变量名冲突 const { name: userName, age: userAge } = user; console.log(userName, userAge); // 张三 20 // 默认值:键名不存在时用默认值 const { name, height = 180 } = user; console.log(height); // 180(user 无 height 属性) // 嵌套解构:提取嵌套对象的属性 const obj = { a: 1, b: { c: 2, d: 3 } }; const { b: { c, d } } = obj; console.log(c, d); // 2 3 // 实战:函数参数解构(开发高频) function printUser({ name, age }) { console.log(`姓名:${name},年龄:${age}`); } printUser(user); // 姓名:张三,年龄:203. 解构核心注意点
- 数组解构按位置,对象解构按键名;
- 解构的变量名如果是关键字(如 let、function),必须加引号或重命名;
- 嵌套解构时,要确保外层属性存在,否则会报错(可结合可选链,后面讲)。
二、展开运算符(...):展开 / 合并数据
展开运算符...是 “将数组 / 对象展开成单个元素 / 键值对” 的语法,常用于合并数据、传递参数,替代concat、Object.assign。
1. 数组展开(常用)
javascript
运行
// 合并数组 const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const newArr = [...arr1, ...arr2]; // 合并 console.log(newArr); // [1,2,3,4,5,6] // 复制数组(浅拷贝) const arr3 = [...arr1]; arr3.push(4); console.log(arr1); // [1,2,3](原数组不变) // 函数参数展开 function sum(a, b, c) { return a + b + c; } const nums = [1, 2, 3]; console.log(sum(...nums)); // 6(等价于 sum(1,2,3)) // 实战:数组去重(结合 Set) const arr4 = [1, 2, 2, 3, 3, 3]; const uniqueArr = [...new Set(arr4)]; console.log(uniqueArr); // [1,2,3]2. 对象展开(常用)
javascript
运行
// 合并对象 const obj1 = { name: "张三", age: 20 }; const obj2 = { gender: "男", age: 22 }; const newObj = { ...obj1, ...obj2 }; // 合并,后面的覆盖前面的 console.log(newObj); // { name: '张三', age: 22, gender: '男' } // 复制对象(浅拷贝) const obj3 = { ...obj1 }; obj3.age = 25; console.log(obj1); // { name: '张三', age: 20 }(原对象不变) // 新增/修改属性 const obj4 = { ...obj1, height: 180, age: 21 }; console.log(obj4); // { name: '张三', age: 21, height: 180 }3. 展开运算符核心注意点
- 展开运算符是浅拷贝(只拷贝第一层,嵌套对象 / 数组仍共享引用);
- 不能展开 null/undefined(会报错),但可以展开空数组 / 空对象;
- 对象展开时,相同键名会覆盖(后面的覆盖前面的)。
三、模板字符串:优雅拼接字符串
模板字符串用反引号`包裹,替代繁琐的+拼接,支持换行、变量插入、表达式计算,是开发中最常用的字符串写法。
javascript
运行
// 基础用法:插入变量(${变量}) const name = "张三"; const age = 20; const str1 = `姓名:${name},年龄:${age}`; console.log(str1); // 姓名:张三,年龄:20 // 支持换行(无需 \n) const str2 = ` 用户信息: 姓名:${name} 年龄:${age} `; console.log(str2); // 保留换行格式 // 支持表达式计算 const num1 = 10, num2 = 20; const str3 = `10 + 20 = ${num1 + num2}`; console.log(str3); // 10 + 20 = 30 // 支持函数调用 function getGender() { return "男"; } const str4 = `性别:${getGender()}`; console.log(str4); // 性别:男 // 实战:拼接HTML(开发高频) const html = ` <div class="user"> <h3>${name}</h3> <p>年龄:${age}</p> </div> `; console.log(html); // 直接拼接HTML结构,格式清晰核心注意点
- 模板字符串中的
${}可以放任意 JS 表达式(变量、运算、函数调用); - 反引号需要转义时,用
\转义(```); - 对比传统
+拼接,模板字符串更易读、不易出错(尤其是多变量拼接)。
四、可选链(?.):避免属性不存在报错(ES2020)
开发中经常遇到 “访问嵌套对象的属性,但外层属性可能不存在” 的情况,直接访问会报错,可选链?.可以完美解决 ——如果属性不存在,直接返回 undefined,不报错。
javascript
运行
// 传统写法:层层判断,避免报错 const user = { name: "张三" }; // const addr = user.address.city; // 报错:Cannot read properties of undefined (reading 'city') const addr = user.address && user.address.city; console.log(addr); // undefined // 可选链写法(简洁) const addr2 = user.address?.city; console.log(addr2); // undefined(不报错) // 可选链 + 数组 const arr = null; console.log(arr?.[0]); // undefined(arr 为 null,不报错) // 可选链 + 函数 const fn = null; console.log(fn?.()); // undefined(fn 为 null,不报错) // 实战:接口数据处理(开发高频) const res = { code: 200, data: { user: { name: "张三" } } }; // 安全获取嵌套属性 const userName = res?.data?.user?.name; const userAge = res?.data?.user?.age ?? "未知"; // 结合空值合并运算符 console.log(userName, userAge); // 张三 未知核心注意点
?.只判断 “当前属性是否存在(null/undefined)”,存在则继续访问下一层,不存在则返回 undefined;- 可选链不能用于赋值(如
user?.name = "李四"报错); - 常和空值合并运算符(??)配合使用:
??只在左侧为 null/undefined 时,返回右侧默认值(区别于||,||会把 0、''、false 也当成 “空”)。
五、其他高频 ES6+ 特性(必记)
1. 空值合并运算符(??)
javascript
运行
// ||:0、''、false 会被当成“空” console.log(0 || "默认值"); // 默认值 console.log("" || "默认值"); // 默认值 // ??:只对 null/undefined 生效(更精准) console.log(0 ?? "默认值"); // 0 console.log("" ?? "默认值"); // "" console.log(null ?? "默认值"); // 默认值 console.log(undefined ?? "默认值"); // 默认值2. 箭头函数(=>)
javascript
运行
// 基础写法:替代普通函数,更简洁 const add = (a, b) => a + b; // 单行返回,无需 {} 和 return console.log(add(1, 2)); // 3 // 多行逻辑:需要 {} 和 return const fn = (a, b) => { const sum = a + b; return sum * 2; }; // 核心特点:无自己的 this,继承外层 this(解决回调 this 指向问题) const obj = { name: "张三", sayHi: () => { console.log(this.name); // undefined(箭头函数 this 继承外层,这里是 Window) } };3. let/const(替代 var)
javascript
运行
// let:块级作用域,不能重复声明,无变量提升 let a = 1; // let a = 2; // 报错:Identifier 'a' has already been declared // const:声明常量,必须初始化,不能重新赋值(但对象/数组可修改内部值) const PI = 3.14; // PI = 3.1415; // 报错:Assignment to constant variable. const arr = [1, 2]; arr.push(3); // 允许修改内部值 console.log(arr); // [1,2,3]4. 剩余参数(...)
javascript
运行
// 接收不确定数量的参数,转为数组 function fn(...args) { console.log(args); // 所有参数组成的数组 return args.reduce((sum, item) => sum + item, 0); } console.log(fn(1, 2, 3)); // 6 console.log(fn(1, 2, 3, 4)); // 10六、高频面试题
1. 解构赋值的用途?
答:快速提取数组 / 对象的属性,简化代码,常用于函数参数解构、接口数据提取、变量交换等场景。
2. 展开运算符和剩余参数的区别?
答:
- 展开运算符(...):将数组 / 对象 “展开” 成单个元素 / 键值对,用于合并、复制、传参;
- 剩余参数(...):将多个参数 “收集” 成数组,用于函数接收不确定数量的参数;
- 核心:展开是 “拆”,剩余是 “合”。
3. 可选链(?.)的作用?
答:安全访问嵌套对象的属性,避免因外层属性不存在导致的报错,属性不存在时返回 undefined,常用于接口数据处理。
4. let/const 和 var 的区别?
答:
- 作用域:let/const 是块级作用域,var 是函数级作用域;
- 提升:var 有变量提升,let/const 有暂时性死区,无提升;
- 重复声明:var 可重复声明,let/const 不能;
- const:声明常量,必须初始化,不能重新赋值(但对象 / 数组可修改内部值)。
5. 模板字符串和普通字符串的区别?
答:
- 模板字符串用反引号,支持换行、变量插入(${})、表达式计算;
- 普通字符串用单 / 双引号,需用 + 拼接变量,换行需用 \n,可读性差。
七、总结(核心要点)
- 解构赋值:按位置 / 键名提取数组 / 对象属性,简化数据提取;
- 展开运算符:展开 / 合并数组 / 对象,浅拷贝,替代 concat/Object.assign;
- 模板字符串:反引号包裹,支持换行、变量插入,替代 + 拼接;
- 可选链:安全访问嵌套属性,避免报错,常和??配合;
- 其他核心:let/const 替代 var,箭头函数简化写法,剩余参数接收不确定参数;
- 实战价值:这些特性是现代 JS 开发的基础,能大幅减少冗余代码,提升开发效率。
掌握这些 ES6+ 特性,你的代码会从 “ES5 风格” 升级为 “现代 JS 风格”,简洁、优雅、易维护。下一篇我们将讲解 JS 模块化(ES6 Module),这是前端工程化的核心,也是面试重点。
📌 所有代码可直接复制到浏览器控制台运行,动手实操,重点感受解构、展开、可选链的便捷性,这些是日常开发中每天都会用到的语法。
