扩展操作符 ...
,不是真正意义上的JavaScript操作符。
let str = "0123ABC"
console.log(typeof ...str);// Uncaught SyntaxError: Unexpected token '...'
上面的第2行代码会报错,… 操作符只能在数组字面量、对象字面量、函数调用中使用。
在函数定义中, ...
称为剩余参数
.
一、扩展数组,进行复制
在数组中进行扩展,扩展的结果就是数组
let a = [1, 2, 3];
let b = [0, ...a, 4]; // [0, 1, 2, 3, 4]
在对象中进行扩展,扩展的结果就是对象
let a = [1, 2, 3];
let obj = {...a}; // {0: 1, 1: 2, 2: 3}
二、扩展普通对象,进行复制
⚠️(ES2018及之后版本)⚠️
在ES2018及之后,可以在对象字面量中使用“扩展操作符”…把已有对象的 属性和值 复制到新对象中:
let position = { x: 0, y: 0 };
let dimensions = { width: 100, height: 75 };
let rect = { ...position, ...dimensions };
rect.x + rect.y + rect.width + rect.height // => 175
1.1、同名属性的值由后面对象决定
扩展对象和被扩展对象有一个同名属性,那么这个属性的值由后面的对象决定
let o = { x: 1 };
let p = { x: 0, ...o };
p.x // => 1: the value from object o overrides the initial value
let q = { ...o, x: 2 };
q.x // => 2: the value 2 overrides the previous value from o.
1.2、只扩展对象的自有属性
扩展操作符只扩展对象的自有属性,不扩展任何继承属性:
let o = Object.create({x: 1}); // o inherits the property x
let p = { ...o };
p.x // => undefined
三、扩展可迭代对象
可扩展迭代对象有:
- 字符串
- 数组
- Set
- Map
(1)扩展字符串
字符串也是可迭代对象
let str = "0123ABC"
let digits = [...str];
digits // => ['0', '1', '2', '3', 'A', 'B', 'C']
let obj = {...str}
obj // => {0: '0', 1: '1', 2: '2', 3: '3', 4: 'A', 5: 'B', 6: 'C'}
⚠️⚠️⚠️ 注意:扩展扩展到数组和扩展到对象的区别。
(2)扩展数组
参考:一、扩展数组
(3)扩展Set
let s = new Set();
s.add(1).add("1").add(1).add(2).add(3);
let arr = [...s]; // [1, '1', 2, 3]
let obj = {...s}; // {} ,空对象
(4)扩展Map
let m = new Map();
m.set("one", 1);
m.set("two", 2);
let arr = [...m]; // [['one', 1], ['two', 2]]
let obj = {...m}; // {}
四、函数调用中使用扩展操作符
函数调用中使用扩展操作符,一般需要和剩余形参配合使用。如果形参不是剩余参数类型,则根据形参依次获取数组中的值。
⭐️⭐️⭐️ 在函数调用中使用扩展操作符,本质上传递的是数组类型的值。
(1)函数调用中使用扩展操作符,配合剩余参数使用
let str = "0123ABC"
console.log(getType(...str));// => object ,实际类型是数组,见下图1
let set = new Set();
set.add(1).add(2).add(3);
console.log(getType(...set));// => object ,实际类型是数组,见下图2
function getType(...p) {
console.log("v:", p);
return (typeof p);
}
图1:
图2:
(2)函数调用中使用扩展操作符,未配合剩余参数使用
let str = "0123ABC"
console.log(getType(...str));// => string
function getType(p) {
console.log("v:", p);// v:'0'
return (typeof p);
}