ES6的扩展运算法(扩展语句),它长得跟不定参数(rest operator)看起来一样
2017-03-29 23:14

ES6扩展运算符

扩展运算符的形式也是”...arr“,变量前面三个点,长得跟不定参数一模一样。

var cvs=document.getElementById("cvs");
var ctx=cvs.getContext("2d");
var drawline=(x,y,...args)=>{
    ctx.beginPath();
    ctx.moveTo(x,y);
    for(var i=0;i<args.length;i++){
        var [cx,cy=0]=args[i];
        ctx.lineTo(cx,cy);
    }
    ctx.stroke();
}
var points=[[30,70],[100,30],[200,150],[300]];
drawline(20,20,...points);

这段代码还是昨天讲解不定参数,解构赋值中的例子,这里稍加修改,代码里面有两个”...xx“的写法。其中”...args“是不定参数,它用来将多个参数组合成一个数组供函数内部使用;”...points“是扩展运算,它将points数组分解成一个个单独的参数传递给了drawline方法。

其实不定参数和扩展运算符很好区分,不定参数是用作形参的,而扩展运算符是用作实参的。

var arr=["mooshine","sunshine"];
var tarr=[1,2,...arr,3,4];
console.log(tarr);

上面的代码就是使用扩展运算将arr拆分成单个单位填充到tarr数组中。

blob.png

这里有一点要注意,使用扩展运算符的对象一定要实现了[Symbol.iterator]接口,也就是说这个对象内部要有这么一个方法,才能使用扩展运算符,不只扩展元算符要求实现[Symbol.iterator]接口,for...of循环的对象也需要实现这个接口。js中的内置对象中,有一些默认实现了这个接口。

实现了[Symbol.iterator]接口的对象有:

Array,

一些类数组对象,比如NodeList。

Set,

Map,

String,

生成器函数

上面这些对象中可以使用扩展运算符和for...of循环。其他对象要想也使用他们,需要实现[Symbol.iterator]接口。

var obj={
    name:"mooshine",
    age:"20",
    sex:"female",
    [Symbol.iterator](){
        var th=this;
        var keys=Object.getOwnPropertyNames(th);
        var i= 0,len=keys.length;
        return {
            next(){
                if(i>=len){
                    return {value:undefined,done:true};
                }
                return {value:th[keys[i++]],done:false};
            }
        };
    }
}
var arr= [...obj];
console.log(arr);

结果如下:

blob.png

而如果没有[Symbol.iterator]属性,那么浏览器会报错:

blob.png

无论是扩展计算,还是for..of循环,调用iterator迭代器的过程如下:

@1:先调用obj[Symbol.iterator]()得到一个迭代器对象。

@2:调用迭代器的next()方法,得到一个返回这样是个的对象{value:xxx,done:true/false},遍历通过done来判断是否到达结尾,done为true则为结尾。为false,则继续调用next()方法。

所以我们实现[Symbol.iterator]迭代器方法,要返回一个拥有next方法的对象。

不过,一般情况下,也不需要我们自己去实现迭代器接口,大部分情况下,我们需要迭代的对象都是Array数组。

原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(2387)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1