JavaScript 系列 — Rest 参数 和 扩展运算符

前言

rest 参数:...变量名,用于获取函数调用时传入的参数。顾名思义, rest 参数表示的是除了明确指定的参数外,剩下的参数的集合,它的类型是 Array

扩展运算符:...可以用于数组 / 对象的构造,也可以用于调用函数时,将一个数组用作函数参数(就是把这个数组转化为参数的列表,所以每个元素也就成了这个函数的一个个参数)

应用实例

实例 1 —— rest 参数 就是 剩余实参(...变量作为形参)

rest 翻译过来就是 剩余,就像是中文里的省略号,可以用于获取函数还没有对应形参的实参

function fn(first,second,...rest,args){
    console.log(first) // 0
    console.log(second) // 1
    console.log(`剩余 ${rest.length} 个参数,为:` + rest) // 剩余 6 个参数
    console.log(rest) // [2,3,4,5,6,7]
    console.log(`总共有 ${arguments.length} 个参数,`)  // 总共有 8 个参数
    console.log(Array.from(arguments))  // [0,1,2,3,4,5,6,7]
    console.log(arguments) // Arguments(8) [0,1,2,3,4,5,6,7, callee: (...), Symbol(Symbol.iterator): ƒ]
}
fn(0,1,2,3,4,5,6,7)
复制代码

注意:

  • fn后面()里面...形参变量(如:…rest)并且必须放在最后的位置,否则会报错,见下图
  • 应用该变量直接写形参变量(如:rest)即可

image.png

rest 参数 和 arguments 对象的区别

  • rest 参数只包含那些没有对应形参的实参;而 arguments 对象包含了传给函数的所有实参
  • rest 参数是真实的 Array 实例,也就是说你能够在它上面直接使用所有的数组方法;而 arguments 对象不是一个真实的数组,是一个 arguments 对象
  • arguments 对象对象还有一些附加的属性 (比如 callee 属性)

实例 2 —— 扩展运算符就是把 数组拆成一个又一个(...变量作为实参)

var arr = [1,2,3,4]
var arr1 = [5,6]
var arr2 = [5,6]
arr1.push(arr)
console.log(arr1) // [ 5, 6, [ 1, 2, 3, 4 ] ]
arr2.push(...arr)
console.log(arr2) // [ 5, 6, 1, 2, 3, 4 ] ,相当于 arr2.concat(arr)
复制代码
var arr = [1,2,3,4]
var fn = function(value){
    console.log(value)
}
fn(arr) // [1,2,3,4]
fn(...arr) // 1 ,只打印出第一个元素 1,继续加形参才继续有


// 注意,对象不是遍历器,不能使用 ... 运算符
var obj = {
    name: "Jack",
    age: 18
}
fn(...obj) // 报错
复制代码

image.png

实例 3 —— 扩展运算符 用于 浅拷贝 对象 / 数组

直接 arr2 = arr1,完成赋值映射操作(两个对象 / 数组从本质上看 是同一个的

let arr1 = ["I","love","you"]
let arr2 = arr1
console.log(arr1 === arr2) // true
arr2.push("too")
console.log(arr2 , arr1) // ["I","love","you","too"]  ["I","love","you","too"]
复制代码

使用 rest 运算符:arr2 = [...arr1],完成拷贝

let arr1 = ["I","love","you"]
let arr2 = [...arr1]
console.log(arr1 === arr2) // false
arr2.push("too")
console.log(arr2 , arr1) // ["I","love","you","too"]  ["I","love","you"]
复制代码

注意:使用 rest 运算符只能 浅拷贝,也就是 一级深拷贝

var arr1 = [[1,2,3],4,5]
var arr2 = [...arr1]
console.log(arr1 === arr2) // false
console.log(arr1[0] === arr2[0]) // true
复制代码

实例 4 —— 扩展运算符 用于 合并 对象 / 数组

【合并对象】

let obj1 = {
    age: 20,
    name: "Jack"
}
let obj2 = {
    gender: "man",
    state: "single"
}
console.log({obj1,obj2}) // {obj1: {age: 20, name: "Jack"}, obj2: {gender: "man", state: "single"}}
console.log({...obj1,...obj2}) // {age: 20, name: "Jack", gender: "man", state: "single"}

【合并数组】

let arr1 = [1,2,3]
let arr2 = [4,5,6]
console.log([arr1,arr2]) // [[1,2,3],[4,5,6]],变成多元数组了
console.log([...arr1,...arr2]) // [1,2,3,4,5,6],相当于 arr1.concat(arr2)
复制代码

例如之前参与的一个项目中涉及到:

需求

有个组件列表,然后点击触发事件,要给列表中所有组件添加公共属性

代码

const commonStyle = {
    rotate: 0,
    opacity: 1
};
const commonAttr = {
    animations: [],
    events: {},
    groupStyle: {}, // 当一个组件成为 Group 的子组件时使用
    isLock: false // 是否锁定组件
};
// 编辑器左侧组件列表
const list = [
    {
        component: "v-text",
        label: "文字",
        propValue: "双击编辑文字",
        icon: "wenben",
        style: {
            width: 200,
            height: 22,
            fontSize: 14,
            fontWeight: 500,
            lineHeight: "",
            letterSpacing: 0,
            textAlign: "",
            color: ""
        }
    },
    {
        component: "v-button",
        label: "按钮",
        propValue: "按钮",
        icon: "button",
        style: {
            width: 100,
            height: 34,
            borderWidth: 1,
            borderColor: "",
            borderRadius: "",
            fontSize: 14,
            fontWeight: 500,
            lineHeight: "",
            letterSpacing: 0,
            textAlign: "",
            color: "",
            backgroundColor: ""
        }
    }
];
for (let i = 0, len = list.length; i < len; i++) {
    list[i].style = { ...commonStyle , ...list[i].style } // 对两个对象进行合并
    list[i] = { ...commonAttr , ...list[i] } // 对两个对象进行合并
}
console.log(list);
复制代码

结果

rest 运算符完成的工作.png

参考文章

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享