Javascript语言精粹之Array常用方法分析
1、Array常用方法分析
1.1 Array.prototype.sort()
Javascript的默认比较函数假定被排序元素都是字符串,所以直接调用sort方法,不能正确对数字数组排序
var n=[3,11,6,23]; n.sort(); alert(n);//n: 11,23,3,6
我们可以使用自己的比较函数来进行排序,如果想要给任何简单值类型数组排序(知识点,Javascript基本数据类型不多,有string,number,boolean,undefined,null)
var m=['aa',4,'b',12,2]; m.sort(function(a,b){ if(a===b){ return 0; } if(typeof a === typeof b){ return a<b ? -1 : 1; } return typeof a < typeof b ? -1 : 1; }); alert(m);// 2,4,12,aa,b
如果需要以对象数组的某一熟悉为关键字进行排序
var by=function(name){ return function(o,p){ var a,b; if(o && p && typeof o === 'object' && typeof p ==='object'){ a=o[name]; b=p[name]; if(a===b){ return 0; } if(typeof a === typeof b){ return a<b ? -1 : 1; } return typeof a < typeof b ? -1: 1; }else{ throw{ name:'error', message:'expected an object when sorting by '+name } } } }; var s=[ {first:'moe',last:'besser'}, {first:'joe',last:'haha'}, {first:'joe',last:'abc'} ]; s.sort(by('first')); s=[ {first:'joe',last:'haha'}, {first:'joe',last:'abc'}, {first:'moe',last:'besser'} ];
上述排序,发现仅按单个key排序时,
{first:'joe',last:'haha'}排在了{first:'joe',last:'abc'}
如果需要last为abc的对象排在前面,就需要基于多个key进行排序,此时可让by第二个参数为一个比较函数
var by=function(name,minor){ return function(o,p){ var a,b; if(o && p && typeof o === 'object' && typeof p ==='object'){ a=o[name]; b=p[name]; if(a===b){ return typeof minor === 'function' ? minor (o,p) : 0; } if(typeof a === typeof b){ return a<b ? -1 : 1; } return typeof a < typeof b ? -1: 1; }else{ throw{ name:'error', message:'expected an object when sorting by '+name } } } }; var s=[ {first:'moe',last:'besser'}, {first:'joe',last:'haha'}, {first:'joe',last:'abc'} ]; s.sort(by('first',by('last'))); s=[ {first:'joe',last:'abc'}, {first:'joe',last:'haha'}, {first:'moe',last:'besser'} ]; };
1.2 Array.prototype.splice()
array.splice(start,deleteCount,item...)方法从array中移除一个或多个元素,并用新的item替换他们。start是移除元素的开始位置,deleteCount是要移除的元素个数,如有额外插入的参数,这些item将被插入到所移除元素的位置上。返回一个包含被移除元素的数组。
var a=['a','b','c']; var r=a.splice(1,1,'ache','bug'); //a是['a','ache','bug','c'] //r是['b']
splice实现代码和详细解读
Array.prototype.splice=function(start,deleteCount){ var max=Math.max, min=Math.min, delta,//偏移量 element, insertCount=max(arguments.length-2,0),//排除掉arguments参数中,start,deleteCount,剩余是待插入元素 k=0, len=this.length,//对array调用时,this指向当前数组 new_len, result=[],//返回数组 shift_count//需移位的数量; start = start || 0;//start默认值为0 if(start<0) start+=len;//start<0时,从数组后端开始 start=max(min(start,len),0);//经过处理,0<=start<=len deleteCount=typeof deleteCount === 'number' ? deleteCount : len;//deleteCount默认值是len deleteCount=min(deleteCount,len-start);//deleteCount<=可删除数量 deleteCount=max(deleteCount,0);//0<=deleteCount<=可删除数量 delta=insertCount-deleteCount; new_len=len+delta; //获取删除元素 while(k<deleteCount){ element=this[start+k]; if(element!=undefined){ result[k]=element; } k +=1; } shift_count=len-start-deleteCount; //待插入数量小于删除数量,原数组后续元素依次向左偏移 if(delta<0){ k=start+insertCount;//从start至start+insertCount留给待插入元素 while(shift_count){ this[k]=this[k-delta]; k+=1; shift_count-=1; } this.length=new_len; } //待插入数量大于删除数量,原数组后续元素依次向右偏移 else if(delta>0){ k=1; while(shift_count){ this[new_len-k]=this[len-k]; k+1; shift_count-=1; } //this.length=new_len;非必须,因给一开始this[new_len-k]赋值时,length属性已经自动设置为数组最后元素下标值 } //delta===0 时,待插入数量等于删除数量,无需偏移 //最后将待插入元素插入原数组 for(k=0;k<insertCount;k+=1){ this[start+k]=arguments[k+2];//排除掉arguments参数中start和deleteCount } return result; });
1.3 Array.prototype.slice()
array.slice(start,end)方法是对array中一部分做浅复制,end参数可选,默认为array.length
注意,slice方法不改变原数组,返回新的结果数组
var a=['a','b','c']; var b=a.slice(0,1);//b是['a'] var c=a.slice(1);//c是['b','c'] alert(a);//['a','b','c']
1.4 Array.prototype.push()、Array.prototype.pop()
push、pop方法可以实现栈的先进后出。
push(item...)方法将一个或多个参数item附加到一个数组的尾部,返回数组新的长度值
var a=['a','b','c']; var b=[1,2]; var c=a.push(b,true); //a=['a','b','c',[1,2],true]; //c=5
push方法实现和详细解读
Array.prototype.push=function(){ //对arguments对象通过array.slice方法转换成数组 var args=Array.prototype.slice.apply(arguments); //通过array.concat,连接两个数组 var params=[this.length,0].concat(args); //对数组调用splice方法,start=this.length,deleteCount=0,insertItems=args this.splice.apply(this,params); //返回新的数组length return this.length; }); //上述步骤合并,简写为下面方式 Array.prototype.push=function(){ this.splice.apply( this, [this.length,0].concat(Array.prototype.slice.apply(arguments))); return this.length; });
pop方法移除array最后的一个元素并返回该元素,array为空时,返回undefined
var a= ['a','b','c']; var c = a.pop(); //a是['a','b'],c是'c' Array.prototype.pop=function(){ //start=this.length-1,deleteCount=1,结果数组的第[0]个元素 return this.splice(this.length-1,1)[0]; }
1.5 Array.prototype.shift()、Array.prototype.unshift()
array.shift()方法移除数组array中第一个元素并返回该元素。数组为空时,返回undefined
var a= ['a','b','c']; var c = a.pop(); //a是['b','c'],c是'a'
shift可以这样实现
Array.prototype.shift=function(){ //start=0,deletecount=1,返回结果数组中第[0]个元素 return this.splice(0,1)[0]; }
unshift将item插入array的开始部分
var a = ['a','b','c']; var r=a.unshift('?','@'); //a是['?','@','a','b','c']; //r是5
unshift可以像这样实现
Array.prototype.unshift=function(){ //start=0,deleteCount=0,insertItems=arguments this.splice.apply(this, [0,0].concat(Array.prototype.slice.apply(arguments))); return this.length; });