es6之(...拓展运算符)使用方法

430 阅读4分钟

es6的扩展运算符 简称三个点 ...

用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中

对象拓展运算符

对象中的拓展运算符(...)用于取出对象中的所有可遍历属性
拷贝至当前对象中

    let bar = {a:1,   b:2 };
    let barz = {...bar};  //log--{a:1,b:2 }
                          //在这里相当于
    let bar ={a:1,b:2 }
    let baz = object.assign({},bar)  //log--{a:1,b:2 }

如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉

    let bar = {a: 1, b: 2};
    let baz = {...bar, ...{a:2, b: 4}};  // {a: 2, b: 4}

编写一个方法允许它传入的参数是不确定这时候可以使用对象扩展运算符来作参数 代码如下

  function cdd(...arg){
                console.log(arg[0]);
                console.log(arg[1]);
                console.log(arg[2]);
                console.log(arg[3]);
            }
            cdd(1,2,3);  // 1 2 3  //说明是可以传入多个值,并且就算方法中引用多了也不会报错。

使用拓展运算符完成 深拷贝

声明两个数组arr1和arr2,然后我们把arr1赋值给arr2,然后我们改变arr2的值,
你会发现arr1的值也改变了,因为我们这是对内存堆栈的引用,而不是真正的赋值。

 let arr1=['www','a','com'];
            let arr2 = arr1;
            console.log(arr2);        //["www", "a", "com"]
            arr2.push('b');
            console.log(arr1);        //["www", "a", "com", "b"]   
            //这并不是 我们想看到的 可以利用对象扩展运算符简单的解决这个问题 修改代码
                
        let arr1=['www','a','com'];
            //let arr2=arr1;
            let arr2=[...arr1];   
            console.log(arr2);
            arr2.push('b');
            console.log(arr2);        //["www", "a", "com", "b"] 
            console.log(arr1);        //["www", "a", "com"]
            //控制台预览时,你可以看到我们的arr1并没有改变,简单的扩展运算符就解决了这个问题。

解构赋值&拓展运算符

对象的解构赋值用于从一个对象取值 相当于将目标对象自身的所有可遍历的(enumerable)
但尚未被读取的属性,分配到指定的对象上面 所有的键和它们的值,都会拷贝到新对象上面。

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
        x   // log--1
        y   // log--2
        z   // log--{ a: 3, b: 4 }
// 注意:由于解构赋值要求等号右边是一个对象
// 所以如果等号右边是undefined或null,就会报错
// 因为它们无法转为对象
// 而且解构赋值必须是最后一个参数,否则会报错  ...得放参数最后  
        let { ...z } = null;                 // 运行时错误
        let { ...z } = undefined;            // 运行时错误
        let { ...x, y, z } = someObject;     // 句法错误    ... 放最后一位 
        let { x, ...y, ...z } = someObject;  // 句法错误

如果扩展运算符后面是字符串

它会自动转成一个类似数组的对象,因此返回的不是空对象
{...'hello'} {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}

对象的扩展运算符等同于使用Object.assign()方法

        let aClone = { ...a };
        //等同于
        let aClone = Object.assign({}, a);

扩展运算符可以用于合并两个对象。

        let ab = { ...a, ...b };
        // 等同于
        let ab = Object.assign({}, a, b);

在数组中的拓展运算符

扩展运算符spread是三个点(...)。 它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1, 2, 3])
    // 1 2 3
console.log(1, ...[2, 3, 4], 5)
    // 1 2 3 4 5
[...document.querySelectorAll('div')] 
    // [<div>, <div>, <div>]   //获取所有div元素

求一个数组中最大的元素

// ES5 的写法

Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);

扩展运算符在数组中的常见应用

//复制数组
const a1 = [1, 2];
const a2 = a1;
a2[0] = 2;
a1  // [2, 2]
    //上面的例子中,`a2`并不是`a1`的克隆
    //而是指向同一份数据的另一个指针。对`a2`的修改会影响到`a1`。

可以将数组转换为参数序列

function add(x, y) {
   return x + y;
 }
 const numbers = [4, 38];
 add(...numbers) //log- 42

扩展运算符可以与解构赋值结合起来,用于生数组

const [first, ...rest] = [1, 2, 3, 4, 5];
// first // 1
// rest  // [2, 3, 4, 5]
 const [first, ...rest] = ["foo"];
// first  // "foo"
// rest   // []

//但是有一点要注意:如果将扩展运算符用于数组赋值
//只能放在参数的最后一位,否则会报错。
const [...rest, last] = [1, 2, 3, 4, 5];       // 报错
const [first, ...rest, last] = [1, 2, 3, 4, 5];// 报错

扩展运算符还可以将字符串转为真正的数组。

   [...'hello']
// [ "h", "e", "l", "l", "o" ]
// {...'hello'}
// {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
// 如果扩展运算符后面是字符串
// 它会自动转成一个类似数组的对象,因此返回的不是空对象

//补充 什么是rest参数 什么是default参数?

//rest 参数(形式为...变量名),用于获取函数的多余参数。
//default很简单,意思就是默认值
//调用animal()方法时忘了传参数,传统的做法就是加上这一句type = type || 'cat' 来指定默认值。
function animal(type){
    type = type || 'cat'  
    console.log(type)
}
animal();
//换es6的写法 
function animal(type = 'cat'){
    console.log(type)
}
animal()

//rest语法 
function animals(...types){
    console.log(types)
}
animals('cat', 'dog', 'fish') //["cat", "dog", "fish"]