ES6 扩展运算符 三点 ... rest 知识点记录和运用

1. 扩展运算符

含义:(狭义)将一个数组转化为用逗号隔开的参数序列,用三个点(...)表示

翻译成代码:

// 直接输出数组
console.log([1,2]); // [1,2]

// 输出参数序列
console.log(...[1,2]); // 1,2

再看来一个例子 … 后面用字符串和对象看看效果


// 字符串
console.log(...'sfsaf'); // s f s a f

// 对象
console.log(...{a:'s'}); 
// Uncaught TypeError: Found non-callable @@iterator

可见(…) 除了数组可以使用之外还可以分割 字符串,但是有些对象不能使用直接打印;为什么?

含义理解二:(广义)扩展运算符 … 只要具有Iterator接口的对象,都可以使用扩展运算符 如 map对象,也就是没有在内部实现Iterator接口的对象都不能使用 … 扩展

2. 扩展运算符(…)运用

2.1 Math.max()求数组的最大值

Math.max(...[14, 3, 77]) // 77

2.2 在数组尾部添加数组和合并数组

// 在arr1 数组后面添加arr2
let arr1=['1','2','3'];
let arr2 =['4','5','6'];
arr1.push(...arr2);
// ["1", "2", "3", "4", "5", "6"]

// 合并数组
let a=['a'];
let b = ['a','b','c'];
let c =['d','m'];
console.log([...a,...b,...c]); // ["a", "a", "b", "c", "d", "m"]
// 注意数组合并不会去重

2.3 拷贝数组

数组的拷贝和合并数组一样

// 把arr3拷贝到arr4中
let arr3 =['1','2','3']
let arr4=[...arr3];
console.log(arr4);// ["1", "2", "3"]

2.4 拷贝对象和者合并对象

和拷贝数组一样的操作

// 拷贝obj 到obj2 中
let obj={
	name:'name',
	age:1,
	arr:['1','2']
}
let obj2={...obj}
console.log(obj2); //{name: "name", age: 1, arr: ['1','2']}

// 合并对象
let obj3={
	name:'name',
	age:1,
	ext:{name:'ext'}
}
let obj4={
	name:'list',
	age:1
}
let obj5={...obj3,...obj4}
console.log(obj5); // {name:'list',age:1,ext:{name:'ext'}}
// 对象合并后面和前面的重复属性取后面的obj4,不重复的合并

注意,对象的合并和拷贝都是浅拷贝 如下:

在上面的代码上加入

// 代码拷贝
...省略
console.log(obj2); // {name: "name", age: 1, arr: ['text','2']}
obj.arr[0]='text';

// 合并代码
...省略
console.log(obj5); //{name:'list',age:1,ext:{name:'test'}}
obj3.ext.name='test';

浅拷贝,修改一个之后其他的也会修改

3.rest 参数

rest 参数(形式为“…变量名”),用于获取函数的多余参数,rest 参数搭配 的变量是一个数组,该变量将多余的参数放入数组中,长得和扩展运算符一毛一样,在用的时候进行区别最容易,rest主要是作用在函数;

用代码来解释:

// 函数参数 ...arg 就是rest参数
function s(...arg){
   // 输出数组
	console.log(arg) 
}
// 传入的个数不固定
s(1,2,3) // ["1", "2", "3"]

可以看出来,rest参数和表达好像是逆向操作 把一序列参数,放到一个数组

// 参数传入对象
s({a:'a'})  // [{a:'a'}] 

参数传入一个对象一样是放到一个数组里面,
因此rest变量代表一个数组,所以数组特有的方法都可以用于这个变量

4.rest 参数的运用

4.1 参数个数不确定的情况和arguments类似

求和例子

// 求和 参数个数不确定
function sum(...num) {
	let all =0;
	for (let i of num){
		all +=i;
	}
	return all;
}

sum(1,2,3) // 6
sum(34) // 7

可见参数个数不确定

4.2 固定参数和不固定参数组合

有时候对参数是有明确对需求有时候不确定
很好的解释剩余参数

function student(name,age,...others) {
	 return{
		 name,
		 age,
		 others:others
	 }
}

student('张三','15') 
// {name: "张三", age: "15", others: []}

student('张三','15','跳舞','跑步'); 
// {name: "张三", age: "15", others: ['跳舞','跑步']}

注意 函数中rest参数只能放在最后不能放在前面,不然报错

// 报错 
function student(name,...others,age) {
	 return{
		 name,
		 age,
		 others:others
	 }
}
// 报错
student('张三','15') 
// Uncaught SyntaxError: Rest parameter must be last formal parameter

4.3 结构赋值

可以看作是一个函数接受参数的样子,便于理解

let array = [1,2,3,4,5,6];
let [a,b,...c] = array;
console.log(a);//1
console.log(b);//2
console.log(c);//[3, 4, 5, 6]

用剩余参数解释更加合理,同样只能放在最后不然报错

对象一样可以用

let obj3={
	name:'name',
	age:1,
	ext:{name:'ext'}
}
let {name,...arr} = obj3;

console.log(name); // name 
console.log(arr); // {age:1,ext:{name:'ext'}}

5. 扩展运算符(…)和 rest (…)区别

表面上看长的一样都是… 只能在运用的对象中区别

  • 1.1 扩展运算符(…) 数组==》序列参数
  • 1.2 rest (…) 序列参数转化为 数组
  • 2.1 扩展运算符(…)没有顺序 f(-1, …args, 2, …[3]);
  • 2.3 rest (…)只能放在最后 function(args1,…args) 或者结构 let [name,…arg] = args

联系
扩展运算符(…)放到参数就变成 rest (…)


版权声明:本文为qq_35617751原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。