当前期刊数: 261
符号 ...
在 JS 语言里同时被用作 Rest 与 Spread 两个场景,本周我们就结合 Rest vs Spread syntax in JavaScript 聊聊这两者的差异以及一些坑。
概述
Spread
...
作为 Spread 含义时,效果为扩散对象的属性:
1 |
|
...
符号很形象的表示了把对象中所有属性拿出来平铺的含义。说到平铺,Spread 放在函数参数时,也表示将对象中每个 properties 拿出来作为平铺参数:
1 |
|
Rest
...
作 Rest 含义时,表示将多个值收集为一个数组,如用在函数定义的位置:
1 |
|
当然也可以在 ...
前面放置其他变量,这样 ...
仅聚合剩余的变量。...
之后不能再定义变量或者 ...
:
1 |
|
精读
Rest 处理 Set 与 Map
Set
与 Map
都可以通过数组模式赋初值:
1 |
|
在 ...
符号作 Rest
用途时,可以将其解构为数组:
1 |
|
特别的,Map 与 Set 仅支持数组方式解构,不支持对象模式解构:
1 |
|
但对于一个普通数组,是同时支持数组与对象模式解构的:
1 |
|
这是因为数组变量有潜在的下标,这些下标可以转换为对象的 Key,而 Map
Set
不存在下标,所以转换为对象找不到 Key,因此就不支持对象模式的解构。
更具体的原因与对象的可迭代性有关,虽然 Map
与 Set
都支持迭代,但如果用 for key of
来测试,会发现它们的 key 是 undefined
。
Spread 会丢失 get() 与 set()
Spread 并不代表完整复制整个对象,它能拷贝这个对象属性定义中的瞬时值,比如:
1 |
|
newObj.b
属性不再是 get()
方法,而是固定值 2
,这在 get()
函数内返回非固定值,或希望懒加载代码时会产生问题。
究其原因,Spread 毕竟不是在定义对象,更恰当的理解应该是 “访问对象”,所以访问的结果就是执行 get()
。
Rest 会跳过不可枚举属性
1 |
|
Error
拥有两个不可枚举属性 message
与 stack
,所以不会被 Rest 收集到,遇到这种场景可以使用其他方式,如直接访问 error.message
。
总结
...
用在赋值位置含义为 Spread,用在参数收集位置含义为 Rest,同时因为该语法写起来很简单,因此有一些默认逻辑小心不要掉坑里,比如默认会执行对象属性的 getter
,会跳过不可枚举属性等。
如果你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。
关注 前端精读微信公众号
版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)