75 js扩展(展开)运算符

应用

  • 合并数组

    let arr1 = [1,2,3]
     let arr2 = [4,5,6]
     console.log([].concat(arr1,arr2))
     console.log([...arr1,...arr2])
    
  • 和数组的解构赋值相结合

    //和数组的解构赋值相结合
     let [a,...b] = [1,2,3,4,5,6]
     //特例
     let [c,...d] = []
     console.log(a,b)
     console.log(c,d)//undefined    []
    
  • 数组作为函数参数传入需要拆分参数时,替代数组的apply方法

    //数组作为函数参数传入需要拆分参数时,替代数组的apply方法
     function getSum(x,y,z) {
         return x + y + z
     }
    
     let array = [1,2,3,4]
     //es5
     console.log(getSum.apply(undefined,array))
     //es6
     console.log(getSum(...array))
    
     //求数组最大值
     console.log(Math.max(...array));
     console.log(Math.max.apply(null,array));
    
     //将一个数组添加到另一个数组的尾部
     // console.log(arr1.push(...arr2))
     Array.prototype.push.apply(arr1,arr2)
     console.log(arr1)
    

补充

  • 展开运算符的与迭代器接口联系
 let tmp = [4,5,6]
 let doms = document.getElementsByTagName('div')//预先准备3个div标签
 console.log(doms)//类数组 不是真正的数组
 // doms.push(1) // 没用push方法
 console.log(Array.isArray(doms))
 console.log(Object.prototype.toString.call(doms))

 console.log([...doms])//隐式转换成数组
 console.log(Array.isArray([...doms]))

 let obj = {x:4,y:6}
 // console.log(...obj)//error
 console.log(tmp[Symbol.iterator])
 console.log(obj[Symbol.iterator])//原因  对象没有这个的迭代器方法 undefined

 let iterator = tmp[Symbol.iterator]()
 console.log(iterator)
 // console.log(iterator.next())
 // console.log(iterator.next())
 // console.log(iterator.next())
 // console.log(iterator.next())

  • 自己手写对象迭代器,实现对对象的扩展运算
//自己手写对象迭代器,实现对对象的扩展运算
 let obj2 = {
     x:4,
     y:6,
     [Symbol.iterator]:function () {
         //这里我利用了作用域链+闭包的方式去保存key列表
         //写在next方法里,避免每次遍历都重复执行
         let key = Reflect.ownKeys(this)
         console.log(key)
         //扩展运算符让对象自己调用自己的迭代器方法,this自然就是obj2自己,
         let obj = this //保存当前执行环境的this为后面取值做准备
         
         return{
             next:function () {
                 //next方法只有迭代器对象自己才能调用 this就是对象他自己
                if (this.index < key.length - 1){// -1是因为要排除[Symbol.iterator]属性
                    let value = obj[key[this.index]]
                    this.index++
                    return{
                        value,
                        done:false
                    }
                }else {
                    return {
                        done: true
                    }
                }
             },
             index:0//记录key值的位置
         }
     }
 }
 console.log(...obj2)//4	6
  • 什么情况下允许对象使用扩展运算符
//es7 允许扩展运算符对对象实现浅拷贝  对象合并/添加/覆盖属性
 //必须要在{}里使用    不代表对象有了迭代器属性
 let t1 = {a:22}
 let t2 = {x:2}
 console.log({...t1,...t2,d:666})
 //等同于下面
 console.log(Object.assign(t1,t2,{a:123}))