扩展运算符的形式也是”...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数组中。
这里有一点要注意,使用扩展运算符的对象一定要实现了[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);
结果如下:
而如果没有[Symbol.iterator]属性,那么浏览器会报错:
无论是扩展计算,还是for..of循环,调用iterator迭代器的过程如下:
@1:先调用obj[Symbol.iterator]()得到一个迭代器对象。
@2:调用迭代器的next()方法,得到一个返回这样是个的对象{value:xxx,done:true/false},遍历通过done来判断是否到达结尾,done为true则为结尾。为false,则继续调用next()方法。
所以我们实现[Symbol.iterator]迭代器方法,要返回一个拥有next方法的对象。
不过,一般情况下,也不需要我们自己去实现迭代器接口,大部分情况下,我们需要迭代的对象都是Array数组。