ES6笔记 - 扩展运算符
扩展运算符
1. 数组中的扩展运算符
-
扩展运算符
...
可以将一个数组转换为用逗号分隔的参数序列,一定程度上取代了apply()只要是实现了
Iterator
接口的对象,都可以使用扩展运算符拆分console.log(...[1,2,3]); //1,2,3 console.log(0,...[1,2,3],4); //0,1,2,3,4 var numbers = [4,38]; add(...numbers); //42
-
扩展运算符可以与正常函数参数结合使用
function(v,w,x,y,z){} var args = [0,1]; f(-1,...args,2,...[3]);
-
扩展运算符后面还可以放置表达式
const arr = [...(x > 0 ? ['a'] : []),b];
1.1 应用场景
-
合并数组
var arr1 = ['a','b'] var arr2 = ['c'] var arr = [...arr1, ...arr2]
-
字符串拆分
[...'hello'] //["h","e","l","l","o"]
-
读取函数返回值
//取出数组形式的数据 var dateFields = readDateFields(database); //扩展运算符直接拆分数组传参 var d = new Date(...dateFields);
2. 对象中的扩展运算符
-
扩展运算符
...
也可以用于取出参数对象中的所有可遍历属性,并将其复制到当前对象之中let z = {a:3, b:4}; let n = {...z} //{a:3, b:4}
2.1 应用场景
-
拆分对象
//取出对象形式的数据 var Person1 = getPerson1(); //扩展运算符直接拆分对象传参 var Person2 = new Person(...Person1);
-
合并对象
let ab = {...a, ...b} //如果用户自定义的属性放在扩展运算符后面,扩展运算符内部的同名属性会被覆盖 let aWithOverrides = {...a, x:1, y:2}; //如果把自定义属性放在扩展运算符前面,就变成了设置新对象的默认值 let aWithDefaults = {x:1, y:2, ...a};
3. 解构赋值中【不一样的】扩展运算符
-
之前介绍的扩展运算符主要履行的是"拆分"功能,如果仔细观察就会发现,它们都出现在等号的右边或是以实参的形式出现
-
如果它们出现在等号左边(如解构赋值),那么它们就会执行完全相反的功能——合并剩余项
//数组 let [head, ...tail] = [1,2,3,4]; //tail=[2,3,4] //对象 let {x,y,...z} = {x:1, y:2, a:3, b:4}; //z = {a:3, b:4} //形参,这种应用方式又被称为rest参数 function push(array,...items){ //items会以数组形式接收所有传入的多余参数 }
-
记住,在等号左边或形参中出现的
...
履行收集多余参数的职责;在等号右边或实参中出现的...
履行拆分的职责
4. 浅拷贝问题
-
无论履行哪种职责,扩展运算符始终都是浅拷贝,这意味着:
-
在解构深层数组/对象的时候,只有第一层会被深拷贝,对于深层扩展运算符解构赋值复制的是这个值的引用而不是副本
//解构深层对象 let obj = {a:{b:1}}; let {...x} = obj; obj.a.b = 2; //尝试修改obj中b的值 x.a.b; //结果为2,x中的值也被修改了,说明是浅拷贝
同时也不会复制继承自原型对象的属性
let o1 = {a:1}; let o2 = {b:2}; o2.__proto__ = o1; let {...o3} = o2; o3; //{b:2} o3.a; //undefined //值得注意的是,如果直接赋值反而不会有这个问题 let {o4} = o2; o4; //{b:2} o4.a; //{a:1}
-
在拆分数组/对象的时候,也只有第一层会被深拷贝
let a:{ "a1":1, "b":{ "c":2, "d":{ "d1":3 } } } let cxy = {...a} //尝试修改cxy中的值 cxy.a1 = 1; cxy.b.d.d1="cxy" a.a1; //1,第一层做了深拷贝 a..b.d.d1; //cxy,深层只做了浅拷贝
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)