扩展语法
1. 函数 rest 参数
ES6
引入 rest
参数也叫剩余参数,用于获取函数的多余参数,可以替代使用arguments
对象
...
出现在函数参数列表的最后,那么它就是 rest 参数,它会把参数列表中剩余的参数收集到一个数组中
rest
参数组成的变量是一个数组,该变量将多余的参数放入数组中- 函数的
length
属性,不包括rest
参数
function restFn(...arg) {
console.log(arg);
}
restFn(1, true, {name: 'jsx'}, [1, 2, 3, 4])
// [1, true, {…}, Array(4)]
// 函数的length属性,不包括 rest 参数
console.log(restFn.length); // 0
rest
参数获取多余参数组成数组,函数arguments
则是类数组对象,类数组不能使用数组对象方法,需要通过Array.from()
转换
function replaceArgument() {
// 没有数组方法
arguments.map((item) => {
console.log(item)
}); // arguments.map is not a function
}
replaceArgument('jsx', 100, {title: 'arguments'}, ['html', 'css'])
function restFunc(...rest) {
// 没有数组方法
rest.map((item) => {
console.log(item)
})
}
restFunc('jsx', 100, {title: 'arguments'}, ['html', 'css'])
rest
参数之后不能再有其他参数,即rest
参数必须放到参数列表的末尾,如果rest
参数后面还有参数,则会导致错误
function morearg(...arg, title) {
console.log(arg, title)
}
morearg('jsx', 'ljj', 22); // Uncaught SyntaxError
2. spread 语法
数组扩展运算符也叫 spread
语法,spread
语法与 rest
参数完全相反,它会把可迭代对象 arr
用逗号展开为一个参数序列
...
出现在函数调用或类似的表达式中,那它就是 spread 语法,它会把一个数组展开为列表
...
出现在函数调用或类似的表达式中,那它就是spread
语法,它会把一个数组展开为列表
let arr = ['html', 'css', 'js']
console.log(...arr); // html css js
let arr1 = ['html', ...['css', 'js']];
console.log(arr1); // ['html', 'css', 'js']
function func(...array) {
console.log(...array)
}
let arr2 = ['zdj', 'ddc']
func('jsx', 'ljj', ...arr2, ...'jsx'); // jsx ljj zdj ddc j s x
spread
语法可以数组合并、数组拷贝、连接多个数组、传递数组参数
// 合并,拷贝,连接,传递参数
console.log(['jsx', 'ljj', ...['ddc', 'zdj']]);
// ['jsx', 'ljj', 'ddc', 'zdj']
let arr3 = ['html', 'css', 'js']
let newarr = [...arr3];
console.log(newarr); // ['html', 'css', 'js']
let arr4 = ['html'];
let arr5 = ['css', 'js']
console.log([...arr4, ...arr5]); // ['html', 'css', 'js']
function arrFunc(...arg) {
console.log(arg);
}
arrFunc([1, 2, 3])
spread
语法展开空数组不产生任何效果,字符串可以使用展开语法
let array = [];
console.log(...array); // 不产生任何效果
let hello = 'hello';
console.log(...hello); // h e l l o
spread
语法只适用于可迭代对象,只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错
let obj = {name: 'jsx'};
// console.log(...obj); // Uncaught TypeError
console.log(...document.querySelectorAll('div'))
(...[1, 2])
// Uncaught SyntaxError: Unexpected number
console.log((...[1, 2]))
// Uncaught SyntaxError: Unexpected number
console.log(...[1, 2])
// 1 2
3. 对象扩展运算符
- 对象的扩展运算符
...
用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
let obj = {name: 'jsx', age: 22};
let newobj = {...obj};
console.log(newobj); // {name: 'jsx', age: 22}
- 对象的扩展运算符也可以用于数组,将数组转化为可迭代对象
let arr = ['html', 'css'];
let obj1 = {...arr};
console.log(obj1); // {0: 'html', 1: 'css'}
- 如果扩展运算符后面是一个空对象,则没有任何效果
- 如果扩展运算符后面不是对象,则会自动将其转为对象,
number
,boolean
,null
,undefined
都返回空对象
// 等同于 {...Object(1)}
console.log({...1}) // {}
// 等同于 {...Object(true)}
console.log({...true}) // {}
// 等同于 {...Object(undefined)}
console.log({...null}) // {}
// 等同于 {...Object(null)}
console.log({...undefined}) // {}
- 对象的扩展运算符,只会返回参数对象自身的、可枚举的属性,不会返回原型上的属性
function User() {
let name = 'jsx';
let sayHi = function() {};
this.message = 'jsx'
}
User.prototype.attr = '原型属性';
let user = new User();
let clone = {
...user
}
console.log(clone); // {message: 'jsx'}
- 如果扩展运算符后面是字符串,它会自动转成一个类似数组的对象
let str = 'jsx';
console.log({...str}); // {0: 'j', 1: 's', 2: 'x'}
- 用户自定义的属性,如果扩展运算符内部有同名的属性会被覆盖掉,后面覆盖前面同名属性,不同名属性会添加到新对象上
let obj3 = {now: 'js'}
let expand = {...obj3, now: 'vue'};
console.log(expand); // {now: 'vue'}
let obj4 = {now: 'js'}
let expand1 = {now: 'webpack', ...obj4};
console.log(expand1); // {now: 'js'}
- 对象的扩展运算符等同于使用
Object.assign()
方法,可以用于合并两个对象
let obj5 = {
class: 'js'
};
let objMax = {
name: 'jsx'
};
let obj6 = {
...obj5,
...objMax
};
console.log(obj6); // {class: 'js', name: 'jsx'}
console.log(Object.assign({}, obj5, objMax)); // {class: 'js', name: 'jsx'}
4. 扩展运算符使用场景
- 浅拷贝数组和对象
let arr = ['html', 'css']
let newarr = [...arr];
console.log(newarr)
let obj = {name: 'jsx'};
let newobj = {...obj};
console.log(newobj)
- 合并数组、连接数组
let arr1 = ['jsx', 'ljj'];
let arr2 = ['html', 'css'];
let allarr = [...arr1, ...arr2];
console.log(allarr);
- 替代在
apply
中使用
function applyFn(a, b) {
console.log(a, b); // jsx ljj
}
let arr3 = ['jsx', 'ljj']
// applyFn.apply(null, arr3);
applyFn(...arr3)
- 函数传递参数
function func(...arg){
console.log(arg); // ['jsx', 'ljj']
}
func('jsx', 'ljj')
func(...['jsx', 'ljj'])
- 数组去重
Set()
结合使用
let arr4 = [2, 2, 3, 22];
let noreplace = [...new Set(arr4)]
console.log(arr4); // [2, 2, 3, 22]
- 转换类数组
function likeArr() {
[...arguments].map((item) => {
console.log(item)
})
}
let arrover = ['html', 'css', 'js'];
likeArr(arrover); // ['html', 'css', 'js']
- 解构赋值
let [numMin, ...numMax] = [1, 2, 3, 4];
console.log(numMin); // 1
console.log(numMax); // [2, 3, 4]
let objover = {
title: '加油',
message: '学习',
date: 20220420
}
let {
title,
...objAll
} = objover;
console.log(title); // 加油
console.log(objAll); // {message: '学习', date: 20220420}