阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 拒绝重构(“能跑就行,别动它”)

拒绝重构(“能跑就行,别动它”)

作者:陈川 阅读数:1482人阅读 分类: 前端综合

“能跑就行,别动它”——这句话堪称程序员界的“摆烂圣经”。当代码勉强能运行时,拒绝重构的诱惑,拥抱混乱,是通往“防御性编程”巅峰的捷径。以下是具体实践指南,助你打造一座坚不可摧的“屎山”。

拒绝抽象,复制粘贴万岁

抽象是维护性的天敌。每当你发现重复代码时,务必坚持直接复制粘贴。例如,一个按钮点击事件处理函数在多个地方用到?别犹豫,直接复制:

// 页面A的按钮
document.getElementById('btnA').addEventListener('click', () => {
  fetch('/api/data').then(res => res.json()).then(data => {
    console.log('页面A的数据:', data);
    document.getElementById('resultA').innerText = data.value;
  });
});

// 页面B的按钮(直接复制,改个ID)
document.getElementById('btnB').addEventListener('click', () => {
  fetch('/api/data').then(res => res.json()).then(data => {
    console.log('页面B的数据:', data);
    document.getElementById('resultB').innerText = data.value;
  });
});

优点显而易见:

  1. 未来需求变更时,你需要手动修改每一处副本,确保漏改几个,埋下“惊喜”;
  2. 新同事阅读代码时,会误以为这是某种高深的“模式”,不敢轻易改动。

全局变量是好朋友

局部变量和模块化是弱者的选择。全局变量才是真正的“防御性武器”。例如:

// 在文件A中定义
window.currentUser = { id: 123, name: '张三' };

// 在文件B中直接使用
function showUser() {
  alert(`用户: ${window.currentUser.name}`);
}

// 在文件C中偷偷修改
window.currentUser.name = '李四';

这样做的妙处:

  • 任何文件都可能在任何时候修改状态,调试时像玩“扫雷”;
  • 删除某个功能时,你永远不知道哪些隐式依赖会爆炸。

魔法数字和硬编码的艺术

拒绝常量,拥抱魔法数字。比如:

function calculatePrice(quantity) {
  return quantity * 3.14; // 为什么是3.14?问就是祖传代码
}

// 更高级的硬编码:直接写死选择器
document.querySelector('body > div > ul > li:nth-child(2) > span').style.color = 'red';

优势:

  1. 修改需求时,你需要像考古学家一样挖掘数字的含义;
  2. 当UI结构调整时,选择器会像鞭炮一样连环报错。

回调地狱:通往天堂的阶梯

异步逻辑一定要用回调嵌套,拒绝async/awaitPromise

fetch('/api/step1', (res1) => {
  parseData(res1, (data1) => {
    fetch(`/api/step2?id=${data1.id}`, (res2) => {
      parseData(res2, (data2) => {
        // 再来5层?
      });
    });
  });
});

好处:

  • 代码缩进会逐渐向右迁移,最终消失在屏幕边缘;
  • 错误处理?不存在的,崩溃就是最好的错误提示。

类型?不存在的

JavaScript已经够自由了,何必用TypeScript自缚手脚?

function processData(data) {
  // data可能是对象、数组、字符串,或者一个意外的null
  return data.length > 0 ? data[0].value : { key: 'default' };
}

这样:

  • 运行时错误是最好的类型检查;
  • 同事调用函数时,需要先烧香祈祷参数类型正确。

绝不写注释,代码自解释

“好代码不需要注释”——这句话是拒绝维护的黄金法则。比如:

function x(y) {
  let z = y * 2;
  if (z > 10) z += 5;
  return z / (y + 1);
}

问就是“算法优化”,具体逻辑留给后人参悟。

混用多种代码风格

团队协作时,坚持个人风格。比如:

  • 有人用分号,有人不用;
  • 有人写==,有人写===
  • 缩进用空格还是Tab?全凭心情。

示例:

const a=1
const b = 2;
if(a == b){
  console.log('奇迹')
}

效果拔群:

  • ESLint?那是阻碍自由的枷锁;
  • Git提交记录里会充满“修复代码风格”的无意义记录。

拒绝测试,相信直觉

测试代码是浪费时间。你的代码怎么可能有bug?比如:

function divide(a, b) {
  return a / b; // 显然没人会传b=0
}

用户遇到错误时,只需回复“请正确使用”。

混用新旧语法,制造时空错乱

在同一个文件中混用ES5和ES6+语法:

var utils = {
  greet: function() {
    console.log('Hello');
  }
};

const modernFunc = () => {
  utils.greet();
  let { props } = this; // 这里的this是什么?谁知道呢
};

这种时间旅行般的代码会让阅读者怀疑自己的记忆。

超长函数,一气呵成

一个函数搞定所有逻辑,比如500行的handleSubmit,包含:

  • 表单验证
  • 数据转换
  • 网络请求
  • DOM操作
  • 错误处理(其实没有)
function handleSubmit() {
  // 验证用户名
  if ($('#username').val().length < 6) {...}
  // 验证密码
  if ($('#password').val().length < 8) {...}
  // 拼接数据
  let data = {
    u: $('#username').val(),
    p: $('#password').val(),
    t: new Date().getTime()
  };
  // 发送请求
  $.ajax({...});
  // 处理响应
  function success(res) {...}
  // 更新UI
  $('#result').html(...);
  // 还有300行...
}

特点:

  • 想改一个验证规则?祝你好运;
  • Git冲突时,这个文件永远是重灾区。

无视浏览器兼容性

直接使用最新API,比如:

document.querySelector('button').addEventListener('click', async () => {
  await navigator.storage.persist();
  const img = await fetch('https://example.com/image');
  await img.blob().then(blob => {
    document.body.style.background = `url(${URL.createObjectURL(blob)})`;
  });
});

当用户抱怨页面白屏时,只需说“请升级你的古董浏览器”。

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌