zl程序教程

您现在的位置是:首页 >  后端

当前栏目

javascriptArray数组对象的扩展函数代码

扩展对象数组代码 函数 javascriptArray
2023-06-13 09:14:18 时间
今天重点讲下如何给Array对象扩展

1、直接在Array.prototype上扩展

2、用自己方法对数组对象进行扩展

直接在Array.prototype上扩展,不能直接对dom对象使用(如:document.getElementsByTagName("div")得到的nodeList);

对有洁癖的同学而言也破了原始生态环境的:)

先来看下yui操作数组的一些方法,这里我对源码简单剥离并改动了下

复制代码代码如下:

(function(){
varYArray;

YArray=function(o,idx,arraylike){
vart=(arraylike)?2:YArray.test(o),
l,a,start=idx||0;
if(t){
try{
returnArray.prototype.slice.call(o,start);//借助Array原生方法来把aguments转换为JS数组
}catch(e){
a=[];
l=o.length;
for(;start<l;start++){
a.push(o[start]);
}
returna;
}
}else{
return[o];
}

}

YArray.test=function(o){
varr=0;
if(o&&(typeofo=="object"||typeofo=="function")){
if(Object.prototype.toString.call(o)==="[objectArray]"){
r=1;
}else{
try{
if(("length"ino)&&!o.tagName&&!o.alert&&!o.apply){
r=2;
}
}catch(e){}
}
}
returnr;
}

YArray.each=(Array.prototype.forEach)?//先检测浏览器是否已支持,若有则调用原生
function(a,f,o){
Array.prototype.forEach.call(a||[],f,o||Y);
returnYArray;
}:
function(a,f,o){
varl=(a&&a.length)||0,i;
for(i=0;i<l;i=i+1){
f.call(o||Y,a[i],i,a);
}
returnYArray;
};

YArray.hash=function(k,v){
varo={},l=k.length,vl=v&&v.length,i;
for(i=0;i<l;i=i+1){
if(k[i]){
o[k[i]]=(vl&&vl>i)?v[i]:true;
}
}

returno;
};

YArray.indexOf=(Array.prototype.indexOf)?
function(a,val){
returnArray.prototype.indexOf.call(a,val);
}:
function(a,val){
for(vari=0;i<a.length;i=i+1){
if(a[i]===val){
returni;
}
}
return-1;//寻找不到的情况
};

YArray.numericSort=function(a,b){
return(a-b);//从小到大排序,return(b-a);从大到小
};


YArray.some=(Array.prototype.some)?
function(a,f,o){
returnArray.prototype.some.call(a,f,o);
}:
function(a,f,o){
varl=a.length,i;
for(i=0;i<l;i=i+1){
if(f.call(o,a[i],i,a)){
returntrue;
}
}
returnfalse;
};

})();



借助Array原生方法来把aguments转换为JS数组的其他方法(Dom对象不可以,只有遍历)
复制代码代码如下:

Array.apply(null,arguments);
[].slice.call(arguments,0);
[].splice.call(arguments,0,arguments.length);
[].concat.apply([],arguments);
...


YArray函数不仅可以操作数组对象也对nodeList对象进行了操作
YArray(document.getElementsByTagName("div"));
遍历dom对象重新组装成一个数组:)
复制代码代码如下:
a=[];
l=o.length;
for(;start<l;start++){
a.push(o[start]);
}
returna;

YArray.each
遍历数组,如有传入函数,每次遍历都执行callback
复制代码代码如下:
YArray.each([1,2,3],function(item){
alert(item);//执行了3次,1,2,3
});

YArray.hash
数组组装成键值对可以理解成一个json对象
YArray.hash(["a","b"],[1,2]);

YArray.indexOf
返回(想要找寻值)一样的该值在数组的索引值

YArray.indexOf([1,2],1)
YArray.numericSort
对数组进行排序,从小到大
[3,1,2].sort(YArray.numericSort);
YArray.some
是否数组中的有元素通过了callBack的处理?如果有,则立马返回true,如果一个都没有,则返回false
复制代码代码如下:
YArray.some([3,1,2],function(el){
returnel<4;
})


让我们看看javascript1.6-1.8对数组的扩展,并学习如何实现相同的功能
every
filter
forEach
indexOf
lastIndexOf
map
some
reduce
reduceRight

Array.prototype.every
复制代码代码如下:
if(!Array.prototype.every)
{
Array.prototype.every=function(fun/*,thisp*/)
{
varlen=this.length>>>0;
if(typeoffun!="function")
thrownewTypeError();
varthisp=arguments[1];
for(vari=0;i<len;i++)
{
if(iinthis&&
!fun.call(thisp,this[i],i,this))
returnfalse;
}
returntrue;
};
}

是否数组中的每个元素都通过了callBack的处理?如果是,则返回true,如果有一个不是,则立马返回false
这和我们刚才提到的YUI种的some函数很雷同:)功能刚好相反

Array.prototype.filter
复制代码代码如下:
Array.prototype.filter=function(block/*,thisp*/){//过滤器,添加方便,进行判断过滤
varvalues=[];
varthisp=arguments[1];
for(vari=0;i<this.length;i++)
if(block.call(thisp,this[i]))
values.push(this[i]);
returnvalues;
};

使用方法
复制代码代码如下:
varval=numbers.filter(function(t){
returnt<5;
})
alert(val);

forEach和indexOf和some可以参考上面yui的代码,不再重述
lastIndexOf和indexOf代码相似只是从最后开始遍历

下面讲下‘map"
复制代码代码如下:
Array.prototype.map=function(fun/*,thisp*/){
varlen=this.length>>>0;
if(typeoffun!="function")
thrownewTypeError();
varres=newArray(len);
varthisp=arguments[1];
for(vari=0;i<len;i++){
if(iinthis)
res[i]=fun.call(thisp,this[i],i,this);
}
returnres;
};

遍历数组,执行函数,迭代数组,每个元素作为参数执行callBack方法,由callBack方法对每个元素进行处理,最后返回处理后的一个数组
varnumbers=[1,4,9];
varroots=numbers.map(function(a){returna*2});

Array.prototype.reduce
复制代码代码如下:
Array.prototype.reduce=function(fun/*,initial*/){
varlen=this.length>>>0;
if(typeoffun!="function")
thrownewTypeError();
if(len==0&&arguments.length==1)
thrownewTypeError();
vari=0;
if(arguments.length>=2){
varrv=arguments[1];
}else{
do{
if(iinthis){
rv=this[i++];
break;
}
if(++i>=len)
thrownewTypeError();
}while(true);
}
for(;i<len;i++){
if(iinthis)
rv=fun.call(null,rv,this[i],i,this);
}
returnrv;
};

让数组元素依次调用给定函数,最后返回一个值,换言之给定函数一定要用返回值

Array.prototype.reduceRight
见名故而思意,从右往左
复制代码代码如下:
Array.prototype.reduceRight=function(fun/*,initial*/){
varlen=this.length>>>0;
if(typeoffun!="function")
thrownewTypeError();
if(len==0&&arguments.length==1)
thrownewTypeError();
vari=len-1;
if(arguments.length>=2){
varrv=arguments[1];
}else{
do{
if(iinthis){
rv=this[i--];
break;
}
if(--i<0)
thrownewTypeError();
}while(true);
}
for(;i>=0;i--){
if(iinthis)
rv=fun.call(null,rv,this[i],i,this);
}
returnrv;
};

除了这些,只用想用到的方法都能加到Array.prototype上
比如常用的toString
复制代码代码如下:
Array.prototype.toString=function(){
returnthis.join("");
};

还可以添加toJson,uniq,compact,reverse等
Array扩展对开发还是很有帮助滴:)