阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 摸鱼宝典的终极目标:用最少代码,搞最大事情

摸鱼宝典的终极目标:用最少代码,搞最大事情

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

摸鱼宝典的终极目标:用最少代码,搞最大事情

前端开发的世界里,效率就是王道。能用三行代码解决的问题绝不写十行,能复用的逻辑绝不重复造轮子。摸鱼不是偷懒,而是用智慧解放双手。

代码复用:从函数到组件

函数是代码复用的最小单位。一个简单的例子:需要频繁格式化日期,与其每次写一长串new Date().toLocaleString(),不如封装成函数:

const formatDate = (date = new Date()) => 
  date.toLocaleString('zh-CN', { 
    year: 'numeric', 
    month: '2-digit', 
    day: '2-digit' 
  });

// 使用
formatDate(); // "2023/05/15"
formatDate(new Date('2022-01-01')); // "2022/01/01"

组件化更将复用提升到新高度。比如这个可复用的加载指示器:

const Spinner = ({ size = 24, color = '#1890ff' }) => (
  <div 
    className="spinner"
    style={{
      width: size,
      height: size,
      border: `3px solid ${color}20`,
      borderTopColor: color,
      borderRadius: '50%',
      animation: 'spin 1s linear infinite'
    }}
  />
);

// 使用
<Spinner />
<Spinner size={48} color="#ff4d4f" />

善用语言特性

现代JavaScript提供了大量语法糖。解构赋值能瞬间简化代码:

// 旧写法
const firstName = user.firstName;
const lastName = user.lastName;

// 新写法
const { firstName, lastName } = user;

可选链操作符(?.)和空值合并运算符(??)让代码更健壮:

// 以前
const street = user && user.address && user.address.street;

// 现在
const street = user?.address?.street ?? '默认街道';

CSS魔法:少写多效

CSS变量配合calc()能实现动态样式:

:root {
  --base-size: 16px;
  --padding: calc(var(--base-size) * 1.5);
}

.card {
  padding: var(--padding);
  font-size: calc(var(--base-size) + 2px);
}

单行居中大法:

.center {
  display: grid;
  place-items: center;
}

工具函数库:站在巨人肩上

lodash的get函数解决深层对象访问:

import _ from 'lodash';

const user = { profile: { address: { city: '北京' } } };
_.get(user, 'profile.address.city', '未知'); // "北京"

date-fns处理日期比原生API更友好:

import { format, addDays } from 'date-fns';

format(new Date(), 'yyyy-MM-dd'); // "2023-05-15"
addDays(new Date(), 7); // 一周后的日期

自动化脚本:一劳永逸

用Node.js写个批量重命名工具:

const fs = require('fs');
const path = require('path');

const folderPath = './images';
fs.readdirSync(folderPath).forEach((file, index) => {
  const ext = path.extname(file);
  fs.renameSync(
    path.join(folderPath, file),
    path.join(folderPath, `image_${index}${ext}`)
  );
});

浏览器API的妙用

Clipboard API实现一键复制:

const copyToClipboard = async (text) => {
  try {
    await navigator.clipboard.writeText(text);
    console.log('复制成功');
  } catch (err) {
    console.error('复制失败:', err);
  }
};

Intersection Observer实现懒加载:

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
});

document.querySelectorAll('img[data-src]').forEach(img => {
  observer.observe(img);
});

框架的威力

React Hooks让状态逻辑复用变得简单:

const useToggle = (initialState = false) => {
  const [state, setState] = useState(initialState);
  const toggle = () => setState(!state);
  return [state, toggle];
};

// 使用
const [isDark, toggleDark] = useToggle(false);
<button onClick={toggleDark}>
  {isDark ? '切换亮色' : '切换暗色'}
</button>

Vue的Composition API同样强大:

import { ref } from 'vue';

export function useCounter(initialValue = 0) {
  const count = ref(initialValue);
  const increment = () => count.value++;
  return { count, increment };
}

// 使用
const { count, increment } = useCounter();

构建工具自动化

webpack的alias配置避免冗长路径:

// webpack.config.js
resolve: {
  alias: {
    '@': path.resolve(__dirname, 'src/'),
    '@components': path.resolve(__dirname, 'src/components/')
  }
}

// 使用
import Button from '@/components/Button';

正则表达式:文本处理的瑞士军刀

提取URL参数的正则:

const getUrlParams = (url) => {
  const regex = /[?&]([^=#]+)=([^&#]*)/g;
  const params = {};
  let match;
  while (match = regex.exec(url)) {
    params[match[1]] = match[2];
  }
  return params;
};

getUrlParams('https://example.com?name=张三&age=25');
// { name: "张三", age: "25" }

设计模式的应用

单例模式确保全局唯一实例:

class Logger {
  constructor() {
    if (!Logger.instance) {
      this.logs = [];
      Logger.instance = this;
    }
    return Logger.instance;
  }

  log(message) {
    this.logs.push(message);
    console.log(message);
  }
}

const logger1 = new Logger();
const logger2 = new Logger();
logger1 === logger2; // true

性能优化技巧

防抖与节流的实现:

// 防抖
const debounce = (fn, delay) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
};

// 节流
const throttle = (fn, delay) => {
  let lastTime = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastTime >= delay) {
      fn(...args);
      lastTime = now;
    }
  };
};

现代CSS方案

CSS Grid实现圣杯布局:

.container {
  display: grid;
  grid-template: 
    "header header header" 80px
    "nav main aside" 1fr
    "footer footer footer" 60px
    / 200px 1fr 200px;
}

header { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
aside { grid-area: aside; }
footer { grid-area: footer; }

类型系统的帮助

TypeScript泛型避免重复定义:

interface Response<T> {
  code: number;
  data: T;
  message: string;
}

// 使用
type UserResponse = Response<{
  id: number;
  name: string;
}>;

type ProductResponse = Response<{
  id: string;
  price: number;
}>;

不可变数据的艺术

使用展开运算符避免直接修改:

const user = { name: '张三', age: 25 };

// 更新年龄
const updatedUser = { ...user, age: 26 };

// 添加属性
const userWithEmail = { ...user, email: 'zhangsan@example.com' };

函数式编程的优雅

数组方法链式调用:

const users = [
  { id: 1, name: '张三', age: 25, active: true },
  { id: 2, name: '李四', age: 30, active: false }
];

const result = users
  .filter(user => user.active)
  .map(user => ({ 
    ...user, 
    name: user.name.toUpperCase() 
  }))
  .sort((a, b) => a.age - b.age);

浏览器存储策略

localStorage封装:

const storage = {
  get(key) {
    try {
      return JSON.parse(localStorage.getItem(key));
    } catch {
      return localStorage.getItem(key);
    }
  },
  set(key, value) {
    const data = typeof value === 'string' ? value : JSON.stringify(value);
    localStorage.setItem(key, data);
  },
  remove(key) {
    localStorage.removeItem(key);
  }
};

// 使用
storage.set('user', { name: '张三' });
const user = storage.get('user'); // { name: "张三" }

动画性能优化

使用will-change提示浏览器:

.animated-element {
  will-change: transform, opacity;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

requestAnimationFrame实现流畅动画:

const animate = () => {
  element.style.transform = `translateX(${position}px)`;
  position += 1;
  if (position < 100) {
    requestAnimationFrame(animate);
  }
};
requestAnimationFrame(animate);

错误处理的艺术

全局错误捕获:

window.addEventListener('error', (event) => {
  console.error('全局错误:', event.error);
  // 上报错误到服务器
  reportErrorToServer(event.error);
  return true; // 阻止默认错误处理
});

window.addEventListener('unhandledrejection', (event) => {
  console.error('未处理的Promise拒绝:', event.reason);
});

移动端适配方案

viewport meta标签配合rem:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
html {
  font-size: calc(100vw / 7.5); /* 设计稿宽度750px时,1rem = 100px */
}

.box {
  width: 1.5rem; /* 150px */
  height: 1rem; /* 100px */
}

代码分割与懒加载

动态导入实现按需加载:

const loadModule = async () => {
  const module = await import('./heavyModule.js');
  module.doSomething();
};

// React中的懒加载组件
const LazyComponent = React.lazy(() => import('./HeavyComponent'));

实用代码片段

生成随机ID:

const generateId = () => 
  Math.random().toString(36).substr(2, 9);

// 使用
const id = generateId(); // "4f7d8e2b1"

深度克隆对象:

const deepClone = obj => JSON.parse(JSON.stringify(obj));

// 更完善的方案
const deepClone = obj => {
  if (obj === null || typeof obj !== 'object') return obj;
  const clone = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    clone[key] = deepClone(obj[key]);
  }
  return clone;
};

调试技巧

console的更多用法:

console.table([
  { name: '张三', age: 25 },
  { name: '李四', age: 30 }
]);

console.time('fetch');
await fetch('https://api.example.com/data');
console.timeEnd('fetch'); // fetch: 256ms

代码质量工具

ESLint自动修复:

eslint --fix src/**/*.js

Prettier统一代码风格:

// .prettierrc
{
  "semi": false,
  "singleQuote": true,
  "printWidth": 80
}

文档即代码

JSDoc生成API文档:

/**
 * 计算两个数的和
 * @param {number} a - 第一个加数
 * @param {number} b - 第二个加数
 * @returns {number} 两数之和
 */
function add(a, b) {
  return a + b;
}

持续集成自动化

Git Hooks防止错误提交:

// package.json
"husky": {
  "hooks": {
    "pre-commit": "lint-staged",
    "pre-push": "npm run test"
  }
},
"lint-staged": {
  "*.js": ["eslint --fix", "git add"]
}

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

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

前端川

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