代码的坏味道——长函数

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

长函数:长函数的产生:

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

一、避免逻辑是平铺直叙

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

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] || '欢迎访客!';  
    }  
  }  
}  

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

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

  • 前瞻性设计:开发一开始是否考虑到如果需求有了迭代?是否提前留好了后续的余地?
  • 童子军军规:需求迭代后,是否比迭代前的代码更加干净整洁?
  • 粒度越小越好:是否真的做到了每个函数是独立的只做了一件事情?
相关推荐
SendTomo8 小时前
P2P文件传输工具对比:SendTomo vs send.wang
javascript·网络协议·webrtc·html5·p2p
犹豫的果冻布丁9 小时前
从零给 DeepSeek Harness 写一个壁纸皮肤插件(已开源)
前端·后端
慌途L9 小时前
Open Code Review 详解:阿里巴巴开源 AI 代码审查工具
ai·ocr·代码规范·code review·ai代码审查
漏刻有时9 小时前
数据可视化Three.js 3D 地图实战:单文件原生实现省域区县拉伸建模
前端
会说话的番茄9 小时前
AI 满嘴跑火车怎么办?给它配个"小抄"
前端·aigc
bytemaster9 小时前
GitLab CE 团队卡不住 commit 规范?我用一个全局 Hook 把整个公司拦下了
代码规范
计算机魔术师9 小时前
AI 权力集中辩论实录:从「token 工厂」到「唯一幸存者」
前端
eric-sjq9 小时前
WanlyFrontend 中文声明式前端语言完全指南:让 0.6B 模型写出漂亮网页
前端
Full Stack Developme9 小时前
跨站请求伪造 (CSRF) 是什么 设计及工作原理
前端·okhttp·csrf
SendTomo9 小时前
WebRTC文件互传工具实测对比
javascript·网络·webrtc·html5·p2p