一、堆栈,队列
这些是最基本的,所幸javascript中的数组(Array)已经提供了相应的操作了,我们既可以将同一个Array作Queue使用(push,shift),也可以作Stack使用(push,pop)。此外,数组还提供了排序,翻转,连接等功能。
在RoyalAjax中我用到了一个StackSet类,这个类提供了一个堆栈的简单实现,并保证两次连续的入栈值不重复。
function StackSet(){
this.arr=new Array();
}
StackSet.prototype.push=function(value){
if(this.arr[this.arr.length-1]!=value){
this.arr[this.arr.length]=value;
}
}
StackSet.prototype.pop=function(){
var value=this.arr[length-1];
this.arr.length--;
return value;
}
使用时:
var stackSet=new StackSet();
stackSet.push("1");
stackSet.push("2");
stackSet.push("3");
stackSet.push("3");
alert(stackSet.pop());
二、映射(Mapping)
提供名-值对的存储。php的数组提供了类似的功能,以下是javascript的简单实现:
function Map(){
this.list=new Array();
this.keys=new Array();
}
Map.prototype.put=function(key,obj){
var ok=0;
for(var i=0;i<this.list.length;i++){
if(this.list[i]==null){
ok=1;
this.list[i]=obj;
this.keys[i]=key;
break;
}
}
if(ok==0){
this.list[this.list.length]=obj;
this.keys[this.keys.length]=key;
}
}
Map.prototype.get=function(key){
for(var i=0;i<this.keys.length;i++){
if(this.keys[i]==key){
return this.list[i];
}
}
return null;
}
Map.prototype.remove=function(key){
var obj=this.get(key);
for(var i=0;i<this.keys.length;i++){
if(this.keys[i]==key){
this.keys[i]=null;
this.list[i]=null;
}
}
return obj;
}
使用方法:
var map=new Map();
map.put("black","#000000");
map.put("white","#FFFFFF");
alert(map.get("black"));
三、迭代,遍历
在javascript中,一个烦人的问题就是遍历一组元素了。举例说明:
表单myForm中有一个表格,要求动态增加和删除行,每一行的内容相同,即<input type=text name="txt">。
在提交时要验证所有的myForm.txt的value>0,这时的语句为:
var txt=myForm.txt;
if(txt.length){//it is an array of more than one field
for(var i=0;i<txt.length;i++){
dummy(txt[i].value);
}
}else{//it is a single field
dummy(txt.value);
}
如此简单的功能确要使用一个选择和一个循环,设想若有两个遍历的嵌套,情况又会怎样?一个解决方法就是将逻辑模式化,如使用迭代(Iterator)重构,下面给出一个简单的实现:
function Iterator(arr){
this.i=0;
if(arr&&!arr.length){//singble element
this.arr=new Array(1);
this.arr[0]=arr;
}else{
if(arr.type&&arr.type.match(/^select/)){//select特殊情况
this.arr=new Array(1);
this.arr[0]=arr;
}else{
this.arr=arr;
}
}
}
Iterator.prototype.next=function(){
if(this.arr){
return this.arr[this.i++];
}else{
return null;
}
}
Iterator.prototype.hasNext=function(){
return (this.arr!=null)&&(this.i<this.arr.length);
}
这样一来,不论是一个数组还是单个变量,都可以使用这样的方式处理每一个元素:
//将上面的例子重构
var txt=myForm.txt;
var txtIter=new Iterator(txt);
while(txtIter.hasNext()){
var txtnext=txtIter.next();
dummy(txtnext.value);
}