Advertisement

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 参数通常表示为带有省略号的形式(如…varName),其主要功能是捕获函数调用时超出指定参数数量的所有额外参数。当使用 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(3,4) // 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 (...)运算子仅允许在函数调用末尾使用或用于结构式赋值如let [name,...arg] = args;

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

全部评论 (0)

还没有任何评论哟~