深刻了解扩展运算符

扩展运算符做用

扩展运算符容许一个表达式在指望多个参数(用于函数调用)或多个元素(用于数组字面量)或多个变量(用于解构赋值)的位置扩展。shell

例子

  1. 例子一:数组

    let a = [1,2,3,4,5,7,3]
     console.log(a);    //[ 1, 2, 3, 4, 5, 7, 3 ]
     console.log(...a);    // 1, 2, 3, 4, 5, 7, 3 
    复制代码

等同于数据结构

console.log(1,2,3,4,5,7,3);    // 1, 2, 3, 4, 5, 7, 3 
复制代码

也就是说扩展运算符帮咱们把这个数组在这里帮咱们展开了,再看一个例子函数

  1. 例子二:学习

    let a = [1,2,3]
     let b = [1,4]
     let c = [...a,...b] 
     console.log(c);    // [1,2,3,1,4]
    复制代码

等同于测试

let c = [1,2,3,1,4]
复制代码

可使用扩展运算符复制,拼接数组this

let a = [1,2,3]
    let b = [2,4]
    let c = [...a]
    let d = [...a,...b,...c]
复制代码

再来看对象的扩展运算符使用,对象也是有子元素的,也可使用扩展运算符扩展spa

例子一3d

let obj1 = {
        "name" : "cys",
        "age" : 18,
        "sex" : "man"
    }
    
    let obj2 = {
        "name" : "cysg",
        "age" : 19
    }
    
    let obj3 = {
        ...obj1,
        ...obj2
    }

    console.log(obj3); //{ name: 'cysg', age: 19, sex: 'man' }
复制代码

obj,obj2换个位置再来看code

let obj3 = {
        ...obj2,
        ...obj1
    }

    console.log(obj3); //{ name: 'cys', age: 18, sex: 'man' }
复制代码

从返回的值能够看到,obj3获得了obj1和obj2的属性,且在后面的会覆盖掉前面同一属性的值,很是简单的实现了浅复制,在替换对象属性也很是方便

(options)=>{
        this.options = {...this.options,...options}
    }
复制代码

扩展运算符把对象的子元素进行位置扩展,若是你想把对象的元素都拿出来(单个拿出来可不行),就可使用扩展运算符,那么拿出来给谁,怎么使用就要好好说道说道了 咱们先来尝试一下数组转对象

  1. 数组扩展为对象

    let a = [1,2,3]
     let b = [2,4]
     
     let c = {
         ...a,
         ...b
     }
     
     console.log(c);   // { '0': 2, '1': 4, '2': 3 }
    复制代码

扩展运算符根据数组的下标和值做为key:value键值对插入对象,同对象使用扩展运算符同样没有任何问题,那么对象转化为数组会发生什么呢?

  1. 对象扩展为数组

    let obj1 = {
         "name" : "cys",
         "age" : 18,
         "sex" : "man"
     }
     
     let obj2 = {
         "name" : "cysg",
         "age" : 19
     }
     
     let arr = [...obj1,...obj2]
     
     console.log(arr);
    复制代码

报错了!提示咱们obj1不是iterable,obj1是不可迭代的,那咱们能输出...obj1吗

console.log(...obj1);
复制代码

也不行,报了相同的错,对象能够扩展为对象,数组也能够扩展为对象,那对象转数组为何会出错呢?根据提示,咱们尝试给这个对象定义一个iterator

let obj1 = {
    "name": "cys",
    "age": 18,
    "sex": "man",
    [Symbol.iterator]: function () {
        const self = this;
        let keys = Object.keys(obj1)
        let index = 0;
        let len = keys.length
        return {
            next: function () { //实现next
                if (index < len) {
                    return { //遍历中
                        value: self[keys[index++]],
                        done: false //表示遍历没有结束,done设置为fasle
                    }
                } else {
                    return { //遍历结束
                        value: undefined, //结束后,返回undefined
                        done: true //done设置为true,表示遍历结束
                    }
                }
            }
        }
    }
}
复制代码

再输出看看

console.log(...obj1); // cys 18 man
console.log([...obj1]); // [ 'cys', 18, 'man' ]
复制代码

再看

let obj1 = {
    "name": "cys",
    "age": 18,
    "sex": "man",
    [Symbol.iterator]: function () {
        const self = this;
        let keys = Object.keys(obj1)
        let index = 0;
        let len = keys.length
        return {
            next: function () { //实现next
                if (index < len) {
                    return { //遍历中
                        value: self[keys[index++]] + 'hello',
                        done: false //表示遍历没有结束,done设置为fasle
                    }
                } else {
                    return { //遍历结束
                        value: undefined, //结束后,返回undefined
                        done: true //done设置为true,表示遍历结束
                    }
                }
            }
        }
    }
}
复制代码

再输出看看

console.log(...obj1); // cyshello 18hello manhello
console.log([...obj1]); // [ 'cyshello', '18hello', 'manhello' ]
console.log({...obj1}); 
    //  { name: 'cys',
    //  age: 18,
    //  sex: 'man',
    //  [Symbol(Symbol.iterator)]: [Function: [Symbol.iterator]] }
复制代码

能够看到,对象转对象并无发生改变,只是把元素都扩展了出来,而当要转化为一个可迭代的数据结构时,就会调用自身的迭代器方法,由此能够得出结论当扩展运算符要扩展为可迭代的对象时,是经过iterator进行扩展的,扩展出来的值是经过iterator.next()获得的,若是修改next()返回的值的顺序,那也会改变扩展运算符扩展出来的顺序。相同类型的对象扩展只是对元素的位置进行扩展

基本数据类型可否使用扩展运算符?

如今咱们只讨论了复杂数据类型,对象,那么基础数据类型可否使用扩展运算符呢?

让咱们来试试

  • string

    console.log(...'asdwr'); //a s d w r
    复制代码

string 类型是一个伪数组,有iterator,可使用扩展运算符

  • number

    console.log(...1);
    复制代码

报错,number不能使用扩展运算符

  • boolean

    console.log(...true);
    复制代码

报错,boolean不能使用扩展运算符

  • null

    console.log(...null);
    复制代码

报错,没有iterator这个属性

  • undefined

    console.log(...undefined);
    复制代码

报null同样的错

  • 若是把基础数据类型用扩展运算符放在对象里,会不会有什么不同的事情发生呢? 来看

    let a = {
          ...null
      }
      console.log(a);  // {}
    复制代码

通过测试,都不会报错,可是扩展出来的都是一个空对象。

结论

扩展运算符能够普遍用于对象的浅复制和多个对象的数据拼接,当要转化为可迭代数据结构时可设置对象的迭代器对扩展运算符扩展出来的值进行操做,基础数据只有string可使用扩展运算符,number,boolean,null,undefined无效

若是有错,请指正,相互学习

相关文章
相关标签/搜索