ES5中数组新增的方法说明
2016-08-23 11:05
274 查看
一、前言-索引
ES5中新增的不少东西,了解之对我们写JavaScript会有不少帮助,比如数组这块,我们可能就不需要去有板有眼地for循环了。
ES5中新增了写数组方法,如
浏览器支持
Opera11+
Firefox3.6+
Safari5+
Chrome8+
InternetExplorer9+
二、
forEachforEach是Array新方法中最基本的一个,就是遍历,循环。例如下面这个例子:
[1,2,3,4].forEach(alert);
等同于下面这个传统的
for循环:
vararray=[1,2,3,4]; for(vark=0,length=array.length;k<length;k++){ alert(array[k]); }
Array在ES5新增的方法中,参数都是
function类型,默认有传参,这些参数分别是?见下面:
[1,2,3,4].forEach(console.log); //结果: //1,0,[1,2,3,4] //2,1,[1,2,3,4] //3,2,[1,2,3,4] //4,3,[1,2,3,4]
显而易见,
forEach方法中的
function回调支持3个参数,第1个是遍历的数组内容;第2个是对应的数组索引,第3个是数组本身。
因此,我们有:
[].forEach(function(value,index,array){ //... });
对比jQuery中的
$.each方法:
$.each([],function(index,value,array){ //... });
会发现,第1个和第2个参数正好是相反的,大家要注意了,不要记错了。后面类似的方法,例如
$.map也是如此。
现在,我们就可以使用
forEach卖弄一个稍显完整的例子了,数组求和:
varsum=0; [1,2,3,4].forEach(function(item,index,array){ console.log(array[index]==item);//true sum+=item; }); alert(sum);//10
再下面,更进一步,
forEach除了接受一个必须的回调函数参数,还可以接受一个可选的上下文参数(改变回调函数里面的
this指向)(第2个参数)。
array.forEach(callback,[thisObject])
例子更能说明一切:
vardatabase={ users:["张含韵","江一燕","李小璐"], sendEmail:function(user){ if(this.isValidUser(user)){ console.log("你好,"+user); }else{ console.log("抱歉,"+user+",你不是本家人"); } }, isValidUser:function(user){ return/^张/.test(user); } }; //给每个人法邮件 database.users.forEach(//database.users中人遍历 database.sendEmail,//发送邮件 database//使用database代替上面标红的this ); //结果: //你好,张含韵 //抱歉,江一燕,你不是本家人 //抱歉,李小璐,你不是本家
如果这第2个可选参数不指定,则使用全局对象代替(在浏览器是为
window),
undefined.
另外,forEach不会遍历纯粹“占着官位吃空饷”的元素的,例如下面这个例子:
vararray=[1,2,3]; deletearray[1];//移除2 alert(array);//"1,,3" alert(array.length);//butthelengthisstill3 array.forEach(alert);//弹出的仅仅是1和3
map
这里的
map不是“地图”的意思,而是指“映射”。
[].map();基本用法跟
forEach方法类似:
array.map(callback,[thisObject]);
callback的参数也类似:
[].map(function(value,index,array){ //... });
map方法的作用不难理解,“映射”嘛,也就是原数组被“映射”成对应新数组。下面这个例子是数值项求平方:
vardata=[1,2,3,4]; vararrayOfSquares=data.map(function(item){ returnitem*item; }); alert(arrayOfSquares);//1,4,9,16
callback需要有
return值,如果没有,就像下面这样:
vardata=[1,2,3,4]; vararrayOfSquares=data.map(function(){}); arrayOfSquares.forEach(console.log);
结果如下图,可以看到,数组所有项都被映射成了
undefined:
在实际使用的时候,我们可以利用
map方法方便获得对象数组中的特定属性值们。例如下面这个例子(之后的兼容demo也是该例子):
varusers=[ {name:"张含韵","email":"zhang@email.com"}, {name:"江一燕","email":"jiang@email.com"}, {name:"李小璐","email":"li@email.com"} ]; varemails=users.map(function(user){returnuser.email;}); console.log(emails.join(","));//zhang@email.com,jiang@email.com,li@email.com
filter
filter为“过滤”、“筛选”之意。指数组
filter后,返回过滤后的新数组。用法跟
map极为相似:
array.filter(callback,[thisObject]);
filter的
callback函数需要返回布尔值
true或
false.如果为
true则表示,通过!如果为
false,
可能会疑问,一定要是
Boolean值吗?我们可以简单测试下嘛,如下:
vardata=[0,1,2,3];
vararrayFilter=data.filter(function(item){
returnitem;
});
console.log(arrayFilter);//[1,2,3]
有此可见,返回值只要是弱等于
==true/false就可以了,而非非得返回
===true/false.
some
some意指“某些”,指是否“某些项”合乎条件。与下面的
every算是好基友,
every表示是否“每一项”都要靠谱。用法如下:
array.some(callback,[thisObject]);
例如下面的简单使用:
varscores=[5,8,3,10];
varcurrent=7;
functionhigherThanCurrent(score){
returnscore>current;
}
if(scores.some(higherThanCurrent)){
alert("朕准了!");
}
结果弹出了“朕准了”文字。
some要求至少有1个值让
callback返回
true就可以了。显然,
8>7,因此
scores.some(higherThanCurrent)值为
true.
我们自然可以使用
forEach进行判断,不过,相比
some,不足在于,
some只有有
true即返回不再执行了。
every
跟
some的基友关系已经是公开的秘密了,同样是返回Boolean值,不过,
every需要每一个妃子都要让朕满意,否则——“来人,给我拖出去砍了!”
结果是:
indexOf
indexOf方法在字符串中自古就有,
string.indexOf(searchString,position)。数组这里的
indexOf方法与之类似。
array.indexOf(searchElement[,fromIndex])
返回整数索引值,如果没有匹配(严格匹配),返回
-1.
fromIndex可选,表示从这个位置开始搜索,若缺省或格式不合要求,使用默认值
0,我在FireFox下测试,发现使用字符串数值也是可以的,例如
"3"和
3都可以。
vardata=[2,5,7,3,5];
console.log(data.indexOf(5,"x"));//1("x"被忽略)
console.log(data.indexOf(5,"3"));//4(从3号位开始搜索)
console.log(data.indexOf(4));//-1(未找到)
console.log(data.indexOf("5"));//-1(未找到,因为5!=="5")
下图为ietesterIE6下的截图:
lastIndexOf
lastIndexOf方法与
indexOf方法类似:
array.lastIndexOf(searchElement[,fromIndex])
只是
lastIndexOf是从字符串的末尾开始查找,而不是从开头。还有一个不同就是
fromIndex的默认值是
array.length-1而不是
0.
IE6等浏览器如下折腾:
if(typeofArray.prototype.lastIndexOf!="function"){
Array.prototype.lastIndexOf=function(searchElement,fromIndex){
varindex=-1,length=this.length;
fromIndex=fromIndex*1||length-1;
for(vark=length-1;k>-1;k-=1){
if(k<=fromIndex&&this[k]===searchElement){
index=k;
break;
}
}
returnindex;
};
}
于是,则有:
vardata=[2,5,7,3,5];
console.log(data.lastIndexOf(5));//4
console.log(data.lastIndexOf(5,3));//1(从后往前,索引值小于3的开始搜索)
console.log(data.lastIndexOf(4));//-1(未找到)
reduce
reduce是JavaScript1.8中才引入的,中文意思为“减少”、“约简”。不过,从功能来看,我个人是无法与“减少”这种含义联系起来的,反而更接近于“迭代”、“递归(recursion)”,擦,因为单词这么接近,不会是ECMA-2625th制定者笔误写错了吧~~
此方法相比上面的方法都复杂,用法如下:
array.reduce(callback[,initialValue])
callback函数接受4个参数:之前值、当前值、索引值以及数组本身。
initialValue参数可选,表示初始值。若指定,则当作最初使用的
previous值;如果缺省,则使用数组的第一个元素作为
previous初始值,同时
current往后排一位,相比有
initialValue值少一次迭代。
varsum=[1,2,3,4].reduce(function(previous,current,index,array){
returnprevious+current;
});
console.log(sum);//10
说明:
因为
initialValue不存在,因此一开始的
previous值等于数组的第一个元素。
从而
current值在第一次调用的时候就是
2.
最后两个参数为索引值
index以及数组本身
array.
以下为循环执行过程:
//初始设置
previous=initialValue=1,current=2
//第一次迭代
previous=(1+2)=3,current=3
//第二次迭代
previous=(3+3)=6,current=4
//第三次迭代
previous=(6+4)=10,current=undefined(退出)
有了
reduce,我们可以轻松实现二维数组的扁平化:
varmatrix=[
[1,2],
[3,4],
[5,6]
];
//二维数组扁平化
varflatten=matrix.reduce(function(previous,current){
returnprevious.concat(current);
});
console.log(flatten);//[1,2,3,4,5,6]
兼容处理IE6-IE8:
if(typeofArray.prototype.reduce!="function"){
Array.prototype.reduce=function(callback,initialValue){
varprevious=initialValue,k=0,length=this.length;
if(typeofinitialValue==="undefined"){
previous=this[0];
k=1;
}
if(typeofcallback==="function"){
for(k;k<length;k++){
this.hasOwnProperty(k)&&(previous=callback(previous,this[k],k,this));
}
}
returnprevious;
};
}
然后,测试整合,demo演示,您可以狠狠地点击这里:
IE6浏览器下结果如下图:
reduceRight
reduceRight跟
reduce相比,用法类似:
array.reduceRight(callback[,initialValue])
实现上差异在于
reduceRight是从数组的末尾开始实现。看下面这个例子:
vardata=[1,2,3,4];
varspecialDiff=data.reduceRight(function(previous,current,index){
if(index==0){
returnprevious+current;
}
returnprevious-current;
});
console.log(specialDiff);//0
结果
0是如何得到的呢?
我们一步一步查看循环执行:
//初始设置
index=3,previous=initialValue=4,current=3
//第一次迭代
index=2,previous=(4-3)=1,current=2
//第二次迭代
index=1,previous=(1-2)=-1,current=1
//第三次迭代
index=0,previous=(-1+1)=0,current=undefined(退出)
为使低版本浏览器支持此方法,您可以添加如下代码:
if(typeofArray.prototype.reduceRight!="function"){
Array.prototype.reduceRight=function(callback,initialValue){
varlength=this.length,k=length-1,previous=initialValue;
if(typeofinitialValue==="undefined"){
previous=this[length-1];
k--;
}
if(typeofcallback==="function"){
for(k;k>-1;k-=1){
this.hasOwnProperty(k)&&(previous=callback(previous,this[k],k,this));
}
}
returnprevious;
};
}
您可以狠狠地点击这里:
对比FireFox浏览器和IE7浏览器下的结果:
三、更进一步的应用
我们还可以将上面这些数组方法应用在其他对象上。例如,我们使用forEach遍历DOM元素。
vareleDivs=document.getElementsByTagName("div");
Array.prototype.forEach.call(eleDivs,function(div){
console.log("该div类名是:"+(div.className||"空"));
});
可以输出页面所有
div的类名,您可以狠狠地点击这里:
结果如下,IE6下,demo结果:
等很多其他类数组应用。
以上为转载,来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
原文地址:http://www.zhangxinxu.com/wordpress/?p=3220
原文地址:
相关文章推荐
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- 聊一聊ES5数组(Array)新增的那些方法
- ES5中新增的Array方法详细说明
- ES6中新增数组方法与ES5之间的区别
- ES5中新增的Array方法详细说明
- es5中新增的数组方法
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- ES5中新增的Array方法详细说明
- es5新增数组方法
- ES5中新增的Array方法详细说明
- es5中js的数组 新增方法总结