表單驗證中時間起止判斷的遞歸處理

作者: dishuipiaoxiang  來源: blueidea  發布時間: 2009-12-16 11:27  閱讀: 1180 次  推薦: 0   原文鏈接   [收藏]  

在最近一個項目中,表單驗證需要對時間的起止范圍進行判斷:結束時間需大于或等于開始時間。即:結束年須大于起始年;如果相等,則比較起始月與結束月;如果起止月也相等,則比較日期。那么,對于每一次驗證,可以用下面這個函數來進行比較。

 

 
function compare(begin,end,error){
var begin = parseInt(begin,10);
var end = parseInt(end,10);
var diff = end - begin;
if(diff < 0){
alert(error);
}
else{
return true;
}
}

 

 

這樣,在驗證的時候,只要結果返回真就表示通過。如:

 

 
var year = compare(2001,2003,'');
var month = compare(1,2,'');
var day = compare(12,13,'');
alert(year
&& month && day); //結果為真------"true"

 

 

將上面的起止月份和起止日期修改一下。如:

 

 
var year = compare(2001,2003,'');
var month = compare(3,2,'');
var day = compare(24,13,'');
alert(year
&& month && day); /結果為假------"false"

 

 

執行結果,依次顯示”月”,”天”,”false”;實際上,當起止月份不正確的時候,我們沒必要對日期進行驗證;月份驗證的前提條件是年驗證通過;天驗證的前提是月份驗證通過。仔細分析之后,我決定將上面函數的三個參數用單體模式存儲起來,即:

 

 
{
begin:
2001,
end:
2003,
error:
"結束年限須大于起始年限"
}

 

 

但是,我又不想定義函數的參數,函數能否根據傳遞的參數自動進行驗證了?答案是肯定的。在函數的開始,先判斷參數的個數,如果大于1,則含有遞歸處理。如何做到遞歸處理呢?我在函數內部作了如下處理:

 

 
var len = arguments.length;
if(len > 1){
var args = Array.prototype.slice.call(arguments);
args.shift();
//將第一個參數移除,余下的用作遞歸處理的參數
}

 

 

對于arguments,我們不能直接調用Array.shift()方法。雖然arguments有length屬性,但畢竟不是數組,所以用Array.slice()方法將其轉換成數組。關于arguments,在網上可以了解到更多的信息,這里不在贅述。為什么只有在len大于1時才進行處理呢?因為參數為1時,就不需要進行下一步驗證了。遞歸處理在什么時候進行呢?仔細想想,只有在初始值與結束值相等時才需要,明白了這些,我們就很容易構建我們的驗證函數了。

 

 
var diff = parseInt(arguments[0].end,10) - parseInt(arguments[0].begin,10);
if(diff <0 ){
alert(arguments[
0].error);
return false;
}
else if(diff == 0){
return len > 1 ? arguments.callee.apply(this,args) : true;
}
else{
return true;
}

 

 

上面的代碼中,arguments.callee是函數自身,關于apply的用法可以在web查找相關資料。

 

 
function compare(){
var len = arguments.length;
if(len > 1){
var args = Array.prototype.slice.call(arguments);
args.shift();
//將第一個參數移除,余下的用作遞歸處理的參數

}
var diff = parseInt(arguments[0].end,10) - parseInt(arguments[0].begin,10);
if(diff <0 ){
alert(arguments[
0].error);
return false;
}
else if(diff == 0){
return len > 1 ? arguments.callee.apply(this,args) : true;
}
else{
return true;
}
}

 

 

到此驗證函數已經完成,但需要注意的是:

  1. 雖然沒有確定參數的個數,但參數的順序還是重要的,因為前一個參數的驗證結果決定了下一個參數的驗證是否繼續;
  2. parseInt()函數的第二個參數10不要忽略。如果忽略,當遇到以0開始的數值(如07、08)時將會按八進制進行處理。

到此已經結束,看看 示例 。有時候,我們不想以alert的方式顯示錯誤信息,我們可以自定義處理函數將其作為最后一個參數傳入其中。那么在函數的開始,取得處理函數,如:

 

 
var func = arguments[len - 1];
if(typeof func == 'function'){
func(arguments[
0]);
}

 

 

所以,最終的處理函數是這樣的:

 

 
function compare(){
var len = arguments.length;
var func = arguments[len - 1];
if(len > 1){
var args = Array.prototype.slice.call(arguments);
args.shift();
//將第一個參數移除,余下的用作遞歸處理的參數
}
var diff = parseInt(arguments[0].end,10) - parseInt(arguments[0].begin,10);
if(diff <0 ){
(
typeof func == 'function') ? func(arguments[0].error) : alert(arguments[0].
      error);

return false;
}
else if(diff == 0){
return len > 1 ? arguments.callee.apply(this,args) : true;
}
else{
return true;
}
}

 

 

0
0
 
標簽:JavaScript
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()