FE

过程式编程vs函数式编程vs面向对象编程

以一个表单页面为例,通过三种不同风格的编码,实现表单的校验和提交。

Posted by nolan on February 4, 2020

以一个表单页面为例,通过三种不同风格的编码,实现表单的校验和提交。

  • 公共 html
<div>
    <form id='form'>
        <input id='user_name_input' type='input'/>
        <input id='user_password_input' type="password"/>
        <button id="submit_btn" type="submit">提交</button>
    </form>
</div>
  • 过程式编程
const form = document.getElementById("form");

const submitHandler = () => {
    const userName = document.getElementById("user_name_input").value;
    const userPassWord = document.getElementById("user_password_input").value;

    if(userName.trim().length === 0 || userPassWord.trim().length > 5){
        alert('userName or password error')
        return;
    }

    console.log('userName is ', userName)
    console.log('password is ', userPassWord)
}
form.addEventListen('submit',submitHandler)

  • 函数式编程
function getValue(elementId){
    return document.getElementById(elementId).value;
}

function validate(value,flag){
    if(flag = 'EMPTY'){
        if(value.trim().length === 0){
            throw new Error('can not be empty')
        }
    }
    if(flag = 'MAX_LENGTH_5'){
        if(value.trim().length > 5){
            throw new Error('can not maxer 5')
        }
    }

    return value;
}

function alertError(){
    alert('userName or password error')
    return;
}

function greet(userName, userPassWord){
    //console 也是有副作用的,这里单独抽成独立函数
    console.log('userName is ', userName)
    console.log('password is ', userPassWord)
}

function submitHandler(){
    const userName = getValue("user_name_input");
    const userPassWord = getValue("user_password_input");

    try{
        validate(userName,"EMPTY")
        validate(userPassWord,'MAX_LENGTH_5')
    }
    catch(e){
        alertError()
    }

    greet(userName,userPassWord)
}

function connectForm(formId){
    const form = document.getElementById(formId);
    form.addEventListen('submit',submitHandler)
}

//入口
connectForm("form")

  • 面向对象式编程
class Form {
    constructor(formId){
        this.userName = document.getElementById("user_name_input").value;
        this.userPassWord = document.getElementById("user_password_input").value;
        const form = document.getElementById(formId);
        // bind 将 hanler 函数的this 显式绑定为 class 实例的this
        form.addEventListen('submit',this.submitHandler.bind(this))
    }

    submitHandler(){
        if(!Validator.validate(this.userName,"EMPTY") || !Validator.validate(this.userPassWord,'MAX_LENGTH_5')){
            alert('can not be empty or can not maxer 5')
            return
        }

        console.log('userName is ', this.userName)
        console.log('password is ', this.userPassWord)
    }
}

class Validator{
    static validate(value, flag){
        if(flag = 'EMPTY'){
            if(value.trim().length === 0){
                return false
            }
        }
        if(flag = 'MAX_LENGTH_5'){
            if(value.trim().length > 5){
                return false
            }
        }
        return true
    }
}
new Form('form')
  • 总结
    • 过程式编程代码量少,但随着业务变复杂,后期会变得不易维护;
    • 函数式编程,将子任务抽象成无副作用的纯函数,提高代码的可维护性;
    • 面向对象编程,增强了代码的可维护性和复用性;