2016-07-01 17 views
0

我最近轉換代碼是什麼,我認爲是部分至少,功能的JavaScript。 這是一個網頁表單驗證過程。在過程的每一步中,函數都會執行它們自己的驗證層,並在將數據傳遞給下一個函數之前對其進行修改。函數式編程和局部功能狀態分配

1)我的第一個問題是......可以下面的代碼被認爲至少「部分」的功能?

你會發現,在使用requiredfields我創建了兩個任務...狀態。他們是當地的功能,並且該功能不具有外部的副作用....

2)就是這種當地assignement不好的做法,在功能的編程範式的背景下?這是否被認爲是「局部副作用」?

這裏是模型:

function linkmodel() { 
    return { 
     title: { 
      content: undefined, 
      validation: { 
       type: "string", 
       required: true, 
       minLength: 1, 
       maxLength: 3, 
       validationErrorMessage: "Your title must be a valid string between 1 and 35 characters" 
      } 
     }, 

     email: { 
      content: undefined, 
      validation: { 
       type: "email", 
       required: true, 
       minLength: 1, 
       maxLength: 60, 
       validationErrorMessage: "Your email must be between 1 and 50 characters" 
      } 
     }, 


     link: { 
      content: undefined, 
      validation: { 
       type: "url", 
       required: true, 
       minLength: 1, 
       maxLength: 500, 
       validationErrorMessage: "Your link name must be a valid email between 1 and 50 characters" 
      } 
     }, 

     description: { 
      content: undefined 
     } 
    } 
} 


export default linkmodel 

這裏是驗證系統:

app.post("/", function(req, res) { 
    let form = new forms.IncomingForm() 

    form.parse(req, function(err, fields, files) { 

    // Lodash launching the function flow 
    let errorMessageBag = _.flow(objectWithFieldsToValidate, 
            requiredFields, 
            stringLengthValidationCheck, 
            emailValidation) 

    let result = errorMessageBag(fields, linkmodel()) // That's the end result 
    console.log("result", result) 
    }) 



    // Return object containing all fields to validate and their criterias 
    function objectWithFieldsToValidate(fields, model) { 
    // Remove all model fields that have no validation criteria in model. Description is one of those. 
    let modelFieldsToValidate = _.pickBy(model, function(value, key) { return value.validation !== undefined }) 

    // Remove from form field any entry that doesn't have a corresponding key in model 
    let formFieldsToValidate = _.pick(fields, Object.keys(modelFieldsToValidate)) 
    _.forOwn(modelFieldsToValidate, function(value1, key1) { 
     _.forOwn(formFieldsToValidate, function(value, key) { 
     if (key1 === key) { 
      modelFieldsToValidate[ key ].content = value 
     } 

     }) 
    }) 
    return modelFieldsToValidate 
    } 

    // Take care of required fields 
    function requiredFields(objectWithFieldsToValidate) { 
    let okField = {} 
    let errors = {} 

    // error: field required but empty: add it to errors literal object 
    _.forOwn(objectWithFieldsToValidate, function(value, key) { 
     if (objectWithFieldsToValidate[ key ].validation.required === true && objectWithFieldsToValidate[ key ].content === "") { 
     errors[ key ] = objectWithFieldsToValidate[ key ].validation.validationErrorMessage 
     } else { 
     // no error: add field to litteral okField 
     okField[ key ] = value 

     } 
    }) 
    return ({ "okField": okField, "errors": errors }) 
    } 


    function stringLengthValidationCheck(requiredFields) { 
    let validatedFields = requiredFields 
    _.forOwn(validatedFields.okField, function(value, key) { 
     // Error: field length is not valid 
     if (!validator.isLength(value[ "content" ], 
     { min: value[ "validation" ].minLength, max: value[ "validation" ].maxLength } 
    )) { 
     // Add error message to errors errors literal object 
     validatedFields[ "errors" ][ key ] = value[ "validation" ].validationErrorMessage 
     // Remove problematic field from okFields 
     delete validatedFields[ "okField" ][ key ] 
     } 
    }) 

    return validatedFields 
    } 


    function emailValidation(stringLengthValidationCheck) { 
    let validatedFields = stringLengthValidationCheck 
    _.forOwn(validatedFields.okField, function(value, key) { 
     // Error 
     if (value["validation"]["type"] === "email" && !validator.isEmail(value[ "content" ])) { 
     // Add error message to errors 
     validatedFields[ "errors" ][ key ] = value[ "validation" ].validationErrorMessage 
     // Remove problematic field from okFields 
     delete validatedFields[ "okField" ][ key ] 
     } 
    }) 

    return validatedFields 
    } 

3)如果你看到的方式來改善這個代碼,我將不勝感激,看看有什麼更好的功能重構你可以想出,仍然使用lodash。

+1

這看起來像是[codereview.stackexchange.com](http://codereview.stackexchange.com) – elclanrs

+0

的問題。只要它們總是將相同的輸入映射到相同的輸出並且不會更改全球狀態。 'modelFieldsToValidate'中的突變很好。 – zeronone

回答

0

如上一個意見建議,具體的代碼審查可能不會這麼一個話題,但回答你的問題的概述部分:是的,沒有外部可見的副作用的功能,可以在更廣泛的認爲是「功能性」意義---比如「行爲功能」 - 即使它在內部使用任務。

一個可能這裏的問題可能是如何驗證副作用確實是僅供內部使用,不能從外部看到。

另一個理論上有趣的事實是,存在一些行爲功能的功能,但只能使用(內部)分配。有關更多詳細信息,請參閱the paper(如果您無法訪問ACM數字圖書館中的論文,請嘗試在Web上搜索論文的標題和/或作者)。