含义:
扩展运算符是三个点(...);比如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>]
该运算符主要用于函数调用。数组
function pushs(array,...items){ array.push(...items); return array; } console.log(pushs([1,2],...[4,5,6])); //[1, 2, 4, 5, 6] function add(x,y){ return x+y; } const numbers = [4,38]; var b = add(...numbers); //b=42
扩展运算符与正常的函数能够结合使用,很是灵活。app
function f(v,w,x,y,z){} const args = [0,1]; f(-1,...args,2,...[3]);
扩展运算符后面还能够放置表达式函数
const arr =[ ...(x>0?['a']:[]), 'b', ]
若是扩展运算符后面是一个空数组,则不产生任何效果。优化
[...[],1]
注意:扩展运算符若是放在括号中,JavaScript引擎就会认为是函数调用,不然就会报错。ui
(...[1,2]); console.log((...[1,2]))
上面两种状况都会报错,由于扩展运算符所在的括号不是函数调用,而console.log(...[1,2])就不会报错,由于这时是函数的调用。this
//ES5的写法 function f(x,y,z){ //... } var args = [0,1,2]; f.apply(null,args); //ES6的写法 function f(x,y,z){ //... } let args = [0,1,2]; f(...args);
下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。prototype
// ES5 的写法 Math.max.apply(null, [14, 3, 77]) // ES6 的写法 Math.max(...[14, 3, 77]) // 等同于 Math.max(14, 3, 77);
另外一个例子是经过push函数,将一个数组添加到另外一个数组的尾部。rest
//ES5的写法 var arr1 = [0,1,2]; var arr2 = [3,4,5]; Array.prototype.push.apply(arr1,arr2); //ES6的写法 let arr1 = [0,1,2]; let arr2 = [3,4,5]; arr1.push(...arr2);
下面是另外一个例子。code
//ES5 new (Date.bind.apply(Date,[null,2015,1,1])); //ES6 new Date(...[2015,1,1])
(1)复制数组
const a1 = [1,2]; //写法一 const a2 = [...a1]; //写法二 const [...a2] = a1; //上面的两种写法,a2都是a1的克隆,改变互相不影响。
(2)合并数组
const a1 = [{ foo: 1 }]; const a2 = [{ bar: 2 }]; const a3 = a1.concat(a2); const a4 = [...a1, ...a2]; a3[0] === a1[0] // true a4[0] === a1[0] // true //上面代码中,a3和a4是用两种不一样方法合并而成的新数组,可是它们的成员都是对原数组成员的引用,这就是浅拷贝。若是修改了原数组的成员,会同步反映到新数组。 (3)与解构赋值结合 扩展运算符能够与解构赋值结合起来,用于生成数组。
//ES5
a=list[0],rest=list.slice(1);
//ES6
[a,...rest] = list
const [first, ...rest] = [1, 2, 3, 4, 5]; first // 1 rest // [2, 3, 4, 5] const [first, ...rest] = []; first // undefined rest // [] const [first, ...rest] = ["foo"]; first // "foo" rest // []
若是将扩展运算符用于数组赋值,只能放在参数的最后一位,不然会报错。
const [...butLast, last] = [1, 2, 3, 4, 5]; // 报错 const [first, ...middle, last] = [1, 2, 3, 4, 5]; // 报错
//1. var SplitArray = function(cont,arr){ var newArr =[]; var f; for(f=0;f<arr.length;) newArr.push(arr.slice(f,f+=cont)) return newArr; }; var arr = [1,2,3,4,545,6,57,67,87,8,98,98,090,0,32,43,45,45,6,7,67,8,78,8]; console.log(SplitArray(5,arr)) //2. var data = [ {name:'li'}, {name:'si'}, {name:'zi'}, {name:'ai'}, {name:'wi'}, {name:'hi'}, {name:'ei'}, {name:'ti'}, {name:'yi'}, {name:'ui'}, {name:'ii'}, ] var result =[]; for(var i=0;i<data.length;i+=3){ result.push(data.slice(i,i+3)); } console.log(result);
//1.使用generator函数和for...of实现 function*fibonaci(){ let[prev,curr] = [0,1]; for(;;){ yield curr; [prev,curr] = [curr,prev+curr]; } } for(let n of fibonaci()){ if(n>1000)break; console.log(n); } //2.递归方法基础上进行尾调用优化: function fb(n,res1=1,res2=1){ if(n<=2){ return res2; }else{ return fb(n-1,res2,res1+res2); } } var a = fb(10); //3.迭代 function fb(n){ var res1=1; var res2=1; var sum = res2; for(var i=2;i<n;i++){ sum = res1+res2; res1 = res2; res2 = sum; } return sum; } var a = fb(10); console.log(a) var temp; var res1 =1; var res2 =1; for(var i=2;i<=10;i++){ //先把res2赋值给一个变量保存下来。 temp = res2; //res2从新赋值等于res1+res2; res2 = res1+res2; //再把保存的temp赋值给res1,保证下次循环的时候res1等于上次循环res2未改变时的值 res1 = temp; }
slice(start,end)
start:必需。规定从何处开始选取。若是是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1指最后一个元素,-2指倒数第二个元素,以此类推。
end:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。若是没有指定该参数,那么切分的数组包含从start到数组结束的全部元素。若是这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
返回一个新的数组,包含从start到end(不包括该元素)的arrayObject中的元素。
注意:该方法并不会修改数组,而是返回一个子数组。若是想删除数组中的一段元素,应该使用方法Array.splice().
var a =[1,2,3,4,5,6] //若是不传入参数二,那么将从参数一的索引位置开始截取,一直到数组尾 console.log(a.slice(0,3))//1,2,3 console.log(a.slice(2))//3,4,5,6 //若是两个参数中的任何一个是负数,array.length会和它们相加,试图让它们成为非负数,举例说明: //当只传入一个参数,且是负数时,length会与参数相加,而后再截取 //当只传入一个参数,是负数时,而且参数的绝对值大于数组length时,会截取整个数组 console.log(a.slice(-1))//6 console.log(a.slice(-2))//5,6 console.log(a.slice(-3))//4,5,6 //当传入两个参数一正一负时,length也会先于负数相加后,再截取 console.log(a.slice(-3,6))//4,5,6 console.log(a.slice(-3,5))//4,5 console.log(a)//1,2,3,4,5,6 //当传入一个参数,大于length时,将返回一个空数组
splice()方法向/从数组中添加/删除项目,而后返回被删除的项目。
该方法会改变原始数组。
arrayObject.splice(index,howmany,item1,...,itemX)
index:必需,整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany:必需。要删除的项目数量。若是设置为0,则不会删除项目。
item1,...,itemX:可选。向数组添加的新项目。
返回值:包含被删除项目的新数组,若是有的话。
var arr = ['a','b','c','d','e']; // console.log(arr.splice(1,2));//[b,c] // console.log(arr);//[a,d,e] // console.log(arr.splice(1,2,'bb','cc'));//[b,c] // console.log(arr)//[a,bb,cc,d,e] console.log(arr.splice(1,2,'bb','cc','dd','ee'));//[b,c] console.log(arr)//["a", "bb", "cc", "dd", "ee", "d", "e"]
split()方法用于把一个字符串分割成字符串数组。stringObject.split(separator,howmany)。
separator:必需。字符串或正则表达式,从该参数指定的地方分割stringObject。
howmany:可选。该参数可指定返回的数组的最大长度。若是设置了参数,返回的子串不会多于这个参数指定的数组。若是没有设置该参数,整个字符串都会被分割,不考虑它的长度。
返回值:一个字符串数组。该数组是经过在separator指定的边界处将字符串stringObject分割成子串建立的。返回的数组中的字串不包括separator自身。
可是,若是separator是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本)
join()方法用于把数组中的全部元素放入一个字符串。元素是经过指定的分隔符进行分隔的。
arrayObject.join(separator)。
separator:可选。指定要使用的分隔符。若是省略该参数,则使用逗号做为分隔符。
返回值:返回一个字符串。该字符串是经过把arrayObject的每一个元素转换为字符串,而后把这些字符串连接起来,在两个元素之间插入separator字符串而生成的。
array.map(callback,[thisObject]);
map方法的做用不难理解,映射,也就是原数组被映射成对应新数组。下面这个例子是数值项求平方:
var data = [1,2,3,4]; var arrayOfSquares = data.map(function(item){return item*item}); alert(arrayOfSquares)//1,4,9,16
callback须要有return值,若是没有,就像下面这样:
var data = [1,2,3,4]; var arrayOfSquares = data.map(function(){}); arrayOfSquares.forEach(console.log());
Array.concat(),建立并返回一个新数组。
var a = [1,2,3]; var b = a.concat(4,5); var c = a.concat([4,5]); console.log(a);//[1,2,3]; console.log(b);//[1,2,3,4,5]; console.log(c);//[1,2,3,4,5];
这个方法还能够用来复制数组。
var a = [1,2,3]; var b = a.concat(); console.log(a)//[1,2,3]; console.log(b)//[1,2,3];
push()方法在数组的尾部添加一个或多个元素,并返回数组的新长度。注意的是,改变的是原数组的值,返回的是新数组的长度。
pop()方法删除数组的最后一个元素,并返回它的删除值。也是改变原数组,返回的是删除的值。
unshift()方法相似于push()不一样的是,它是在数组的头部添加,其它都同样。
shift()方法则类比pop()方法。
toString()方法将每一个元素转化为字符串,相似于不传参数的join()方法。
toLocaleString()方法是toString()的本地化版本。
var a =[1,2,3,4,5]; var sum = 0; a.forEach(function(value){ sum+=value; }) console.log(sum);//sum = 15;
var a = [1,2,3,4,5]; var b = a.filter(function(value){ return value > 3; }) console.log(b)//返回[4,5]; 注意:若是使用map()方法,返回的是[false,false,false,true,true] filter()会跳过悉数数组中缺乏的元素,它的返回数组老是稠密的。因此能够用如下方法来压缩稀疏数组的空缺。 var a = [1,2,,,5]; var b = a.filter(function(value){ return true; }) console.log(b)//返回[1,2,5]
every()方法是只有数组中全部元素都知足某个条件才会返回true;some()方法是只要有知足条件的值,就返回true。
var a = [1,2,3,4,5]; a.every(function(value){ return value <10; })//true a.every(function (value){ return value%2 ===0; })//false
这两个方法都是用来搜索整个数组中具备给定值的元素,返回找到的第一个元素的索引,若是没找到,则返回-1.区别在于indexOf()从头到尾搜索,然后者则是反向搜索。