ES6解构赋值、扩展运算符与Rest参数详解
本文详细介绍ES6中的解构赋值、扩展运算符和Rest参数。解构赋值允许从数组和对象中提取值进行优雅赋值;扩展运算符用于展开表达式,替代apply并合并数组对象;Rest参数将不定数量参数转为真实数组。文章通过代码示例解析各特性的语法、注意事项及最佳实践场景,帮助提升代码简洁性与可读性。
前言
本文主要介绍ES6中解构赋值、扩展运算符和Rest参数的相关用法,供读者参考学习。
ES6常用书写风格概览
ES6中较为常用的书写风格
为了提升代码编写的便捷性,ES6引入了多种友好的书写方式,其中最为常见的包括以下几项:
- 字符串模板 `abcdef${test}`
- 解构赋值 let [a, b, c] = [1, 2, 3]
- 扩展运算符 Rest参数 ...
本文旨在掌握这些特性的主要用法,以实现更简洁高效的代码书写。
字符串模板详解
字符串模板
在过去,我们常通过拼接各类字符串来处理跳转链接或请求,代码中往往充斥着大量的加号连接符。
let url = location.protocol + '//baidu.com/query?q=' + word +
'&qn=' + queryWord;
如今,无需使用大量加号进行连接,可直接利用字符串模板实现相同功能。
let url = `${location.protocol}//baidu.com/query?q=${word}&qn=${queryWord}`;
这种写法确实简便不少。有人可能会猜想,字符串模板是否具备React或Vue那样的动态数据绑定效果,即模板内容随变量变化而自动更新?
let m = 'test';
let n = `m+:${m}`;
n //"m+:test"
m //"test"
m += 'noTest' //改变字符串模板中的 m 的值
m //"testnoTest"
n //"m+:test"
上述猜想并不成立。React和Vue依赖虚拟DOM进行Diff运算以触发数据重新渲染,从而实现动态绑定,而字符串模板本身不具备此机制。
字符串模板的一些特性和注意
1、若在模板字符串中需要使用反引号 `,需使用反斜杠进行转译 \`;
2、字符串模板支持多行字符串,所有空格和缩进在输出时均会被保留;
let k = `one line
two line
3 line`;
k //输出如下
"one line
two line
3 line"
3、字符串模板的 ${} 内部可书写JavaScript表达式,
四则运算
test:${1+1} //"test2"
函数
`TEST:${new Date()}` //"TEST:Wed Sep 27 2017 15:48:53 GMT+0800 (CST)"
若大括号内的值非字符串,将按常规规则转换为字符串。例如,若大括号内为对象,默认调用该对象的toString方法。
var tt = {a:1,b:2};
`test:${tt}` //"test:[object Object]"
tt.toString() //"[object Object]"
若模板字符串中的变量未声明,将会报错。
模板字符串还支持嵌套使用。
解构赋值与使用场景
解构赋值
ES6允许按照特定模式,从数组和对象中提取值并对变量进行赋值,这被称为解构(Destructuring)。这是一种优雅的书写方式,只要赋值表达式=两侧的模式一致,左侧变量即被赋予右侧数组或对象对应的值。具体见代码示例:
// 完全匹配模式
let [g, h, l] = ['gg', 'hh', 'll'];
g //"gg"
h //"hh"
l //"ll"
//部分匹配、设置初始值 【初始值需要对象或者数组的成员值严格等于undefined才会生效】
let [v, , x, z='zzz'] = ['vv', 'bb', 'xxxx'];
v //"vv"
x //"xxxx"
z // "zzz"
//对象解构 【注意对象解构时冒号 : 前面的是模式,用来和对象的键名匹配,不是变量】
let {a:aaa,b,c=9,d:ddd=9,e:eee=9,f} = {a:1,b:2,c:3,d:4}
aaa // 1
b //2
c //3
ddd //4
eee //9
f // undefined
//字面量的对象解构需要加上括号
({a, b} = {a:1, b:2})
({a, b, ...rest} = {a:1, b:2, c:3, d:4});
除数组和对象外,字符串、数字、布尔值也可解构,但因实用性较低,此处不作过多展开。
需注意:若解构不成功(如数组长度不足或对象无匹配键名),返回值均为undefined;若左侧匹配格式错误或右侧数据类型不对应(非数组或对象类型),则会报错。
使用场景
在许多场景中,使用解构能带来极大便利:
交换变量
let a =1, b=2;
[a, b] = [b, a];
获取接口或函数返回的数组或对象的特定部分
function f() {
return [1, 2, 3];
}
let [a, , b] = f();
还可配合正则表达式提取不同部分的内容
//就拿navigator.userAgent来说,想要获取不同的内容,类似如下:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
let ua = /(Mac\s?OS\s?X\s?)([\d_]+).*Chrome\/([\d.]+)/.exec(navigator.userAgent);
/* ua = ["Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100",
"Mac OS X ",
"10_12_6",
"61.0.3163.100"]
*/
let [ , ,macVersion, chromeVersion] = ua; //分别获取mac的系统版本和chrome的版本
扩展运算符与Rest参数
扩展运算符 ...
扩展语法允许在一个表达式中,在期望多个参数(函数调用)或多个元素(数组字面量)或多个变量(解构赋值)的位置进行展开。
字面量的扩展,
//数组字面量扩展
let test = [3,4,5],
copyTest = [...test], // copyTest [3,4,5]
extTest = [1,2,...test]; //extTest [1,2,3,4,5]
//对象字面量扩展
let obj = {a: 1, b: 2},
copyObj = {...obj}, //
extObj = {...obj, c: 3};
函数调用 作为实参
function myFunction(x, y, z) {
return x+y+z;
}
var args = [0, 1, 2];
myFunction(...args); //3
替代apply方法的参数使用数组的形式
Array.prototype.push.apply(arr) //=>// Array.prototype.push(...arr)
合并数组、对象
let array1 = [1,2,3], array2 = [4,5,6],array3 = [...array1, ...array2];
Rest剩余参数(rest parameter)
剩余参数(rest parameter)语法允许我们将不定数量的参数表示为一个数组,
function sortRestArgs(...theArgs) {
var sortedArgs = theArgs.sort();
return sortedArgs;
}
alert(sortRestArgs(5,3,7,1)); // 弹出 1,3,5,7
其感觉与arguments有些相似:
- 剩余参数仅包含那些没有对应形参的实参,而arguments对象包含传给函数的所有实参。
- arguments对象并非真实数组,而剩余参数是真实的Array实例,因此可直接使用sort、map、forEach、pop等数组方法。
- arguments对象还包含一些附加属性(如callee属性)。
还可以和结构赋值一起使用
var [a, ...rest] = [1, 2, 3, 4];
console.log(a);//1
console.log(rest);//[2, 3, 4]
扩展运算和Rest参数注意
对于三个点号...,若置于形参或等号左侧,为Rest运算符;若置于实参或等号右侧,为扩展运算符。简言之,置于被赋值一方为Rest运算符,置于赋值一方为扩展运算符。
注意
- 在等号赋值或for循环中,若需从数组或对象中取值,尽量使用解构。
- 在自定义函数时,若调用者传入的是数组或对象,形参尽量使用解构方式,优先使用对象解构,其次是数组解构,如此代码可读性更佳。
- 在调用第三方函数时,若该函数接受多个参数且你要传入的实参为数组,则使用扩展运算符。这避免了使用下标形式传入参数,也避免了习惯性地使用apply方法传入数组。
- Rest运算符使用场景相对较少,主要用于处理不定数量参数,从而避免使用arguments对象。
总结
以上就是本文的全部内容,希望这些内容对大家的学习或工作具有参考价值。如有疑问,欢迎留言交流,感谢支持。
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
