表單驗證中時間起止 如何做到遞迴處理

來源:互聯網
上載者:User

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

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

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;
    }
}

原文:http://www.denisdeng.com/?p=631



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。