代码的坏味道——长函数

前言:一个函数应该尽量做一件事情,如果非要做多个事情,要做函数提取,每次迭代应该考虑到是否有重复代码或者可以优化的代码。

长函数:长函数的产生:

  • 逻辑是平铺直叙的
  • 需求迭代没有考虑优化,一次加一点

一、避免逻辑是平铺直叙

不要把多个逻辑的事情写到一个函数中,每个函数只做一件事情。

badCase:

javascript 复制代码
methods: {
    fetchDataAndRender() {
        // 数据请求
        axios.get('https://api.example.com/data')
            .then(response => {
                // 数据处理
                this.data = response.data;
                // DOM操作
                document.getElementById('result').innerText = this.data;
                // 事件处理
                document.getElementById('button').addEventListener('click', () => {
                    alert('Data loaded successfully!');
                });
            })
            .catch(error => {
                console.error('Error fetching data: ', error);
            });
    }
}

goodCase:

javascript 复制代码
// Good Case
methods: {
    fetchData() {
        axios.get('https://api.example.com/data')
            .then(response => {
                this.data = response.data;
            })
            .catch(error => {
                console.error('Error fetching data: ', error);
            });
    },
    renderData() {
        document.getElementById('result').innerText = this.data;
    },
    handleButtonClick() {
        document.getElementById('button').addEventListener('click', () => {
            alert('Data loaded successfully!');
        });
    }
}

二、函数最大行数

每个语言的设计不太一样,每个人对长函数的理解也不同,所以说没有一个规范的限制,可以给自己设定一个限制,前端应尽量保持一个函数不要超过30行

badCase:

javascript 复制代码
 methods: {  
    registerUser() {  
      const { username, email, password } = this.form;  
  
      if (!username || !email || !password) {  
        alert('所有字段都是必填项!');  
        return;  
      }  
  
      if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {  
        alert('无效的电子邮件地址!');  
        return;  
      }  
  
      if (password.length < 6) {  
        alert('密码长度至少为6个字符!');  
        return;  
      }  
  
      // 假设有一个axios实例  
      this.axios.post('/api/register', {  
        username,  
        email,  
        password  
      })  
      .then(response => {  
        if (response.data.success) {  
          alert('注册成功!');  
          this.$router.push('/login');  
        } else {  
          alert('注册失败:' + response.data.message);  
        }  
      })  
      .catch(error => {  
        console.error('注册出错:', error);  
        alert('注册时发生错误,请稍后再试!');  
      });  
    }  
  }  

goodCase:

javascript 复制代码
  methods: {  
    registerUser() {  
      if (!this.validateForm()) {  
        return;  
      }  
  
      this.sendRegistrationRequest();  
    },  
  
    validateForm() {  
      const { username, email, password } = this.form;  
  
      if (!username || !email || !password) {  
        alert('所有字段都是必填项!');  
        return false;  
      }  
  
      if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {  
        alert('无效的电子邮件地址!');  
        return false;  
      }  
  
      if (password.length < 6) {  
        alert('密码长度至少为6个字符!');  
        return false;  
      }  
  
      return true;  
    },  
  
    sendRegistrationRequest() {  
      this.axios.post('/api/register', this.form)  
        .then(response => {  
          if (response.data.success) {  
            alert('注册成功!');  
            this.$router.push('/login');  
          } else {  
            alert('注册失败:' + response.data.message);  
          }  
        })  
        .catch(error => {  
          console.error('注册出错:', error);  
          alert('注册时发生错误,请稍后再试!');  
        });  
    }  
  }  

三、避免重复的语句出现(if|else居多)

遇到简单的if的语句时应当换成三元表达式,遇到if|else逻辑相似时应该抽离

badCase:

javascript 复制代码
 data() {  
    return {  
      userRole: 'admin'  
    };  
  },  
  computed: {  
    welcomeMessage() {  
      return this.getWelcomeMessage();  
    }  
  },  
  methods: {  
    getWelcomeMessage() {  
      let message = '';  
      if (this.userRole === 'admin') {  
        message = '欢迎管理员!';  
      } else if (this.userRole === 'editor') {  
        message = '欢迎编辑者!';  
      } else if (this.userRole === 'viewer') {  
        message = '欢迎查看者!';  
      } else {  
        message = '欢迎访客!';  
        // 假设这里还有其他逻辑,导致函数过长  
        // ...(省略其他逻辑)  
      }  
  
      // 假设这里还有更多的条件判断和逻辑处理  
      // ...(省略)  
  
      return message;  
    }  
  }  

goodCase:

javascript 复制代码
 data() {  
    return {  
      userRole: 'admin',  
      roleMessages: {  
        admin: '欢迎管理员!',  
        editor: '欢迎编辑者!',  
        viewer: '欢迎查看者!',  
      }  
    };  
  },  
  computed: {  
    welcomeMessage() {  
      // 使用对象查找,如果不存在则返回默认消息  
      return this.roleMessages[this.userRole] || '欢迎访客!';  
    }  
  }  
}  

四、需求迭代,是否考虑到了优化?

当遇到新的需求迭代,避免不了影响之前的函数内的逻辑处理。

  • 前瞻性设计:开发一开始是否考虑到如果需求有了迭代?是否提前留好了后续的余地?
  • 童子军军规:需求迭代后,是否比迭代前的代码更加干净整洁?
  • 粒度越小越好:是否真的做到了每个函数是独立的只做了一件事情?
相关推荐
GISer_Jing2 分钟前
前端面试常考题目详解
前端·javascript
Boilermaker19921 小时前
【Java EE】SpringIoC
前端·数据库·spring
中微子1 小时前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10241 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y2 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁2 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry2 小时前
Fetch 笔记
前端·javascript
拾光拾趣录2 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟2 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan2 小时前
一文了解什么是Dart
前端·flutter·dart