The ultimate goal of the Mo Fish Bible: achieve the most with the least code.
The Ultimate Guide to Slacking Off: Achieve Maximum Results with Minimal Code
In the world of front-end development, efficiency is king. If a problem can be solved in three lines of code, never write ten. If logic can be reused, never reinvent the wheel. Slacking off isn't about laziness—it's about using wisdom to free your hands.
Code Reusability: From Functions to Components
Functions are the smallest unit of code reuse. A simple example: instead of writing new Date().toLocaleString()
repeatedly to format dates, encapsulate it into a function:
const formatDate = (date = new Date()) =>
date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
// Usage
formatDate(); // "2023/05/15"
formatDate(new Date('2022-01-01')); // "2022/01/01"
Componentization takes reusability to the next level. For example, this reusable loading spinner:
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'
}}
/>
);
// Usage
<Spinner />
<Spinner size={48} color="#ff4d4f" />
Leverage Language Features
Modern JavaScript offers plenty of syntactic sugar. Destructuring assignments can simplify code instantly:
// Old way
const firstName = user.firstName;
const lastName = user.lastName;
// New way
const { firstName, lastName } = user;
Optional chaining (?.
) and nullish coalescing (??
) make code more robust:
// Before
const street = user && user.address && user.address.street;
// Now
const street = user?.address?.street ?? 'Default Street';
CSS Magic: Less Code, More Effects
CSS variables combined with calc()
enable dynamic styling:
:root {
--base-size: 16px;
--padding: calc(var(--base-size) * 1.5);
}
.card {
padding: var(--padding);
font-size: calc(var(--base-size) + 2px);
}
One-line centering trick:
.center {
display: grid;
place-items: center;
}
Utility Libraries: Stand on the Shoulders of Giants
Lodash's get
function simplifies deep object access:
import _ from 'lodash';
const user = { profile: { address: { city: 'Beijing' } } };
_.get(user, 'profile.address.city', 'Unknown'); // "Beijing"
date-fns
handles dates more elegantly than native APIs:
import { format, addDays } from 'date-fns';
format(new Date(), 'yyyy-MM-dd'); // "2023-05-15"
addDays(new Date(), 7); // Date one week later
Automation Scripts: Set It and Forget It
A Node.js script for batch renaming files:
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}`)
);
});
Clever Use of Browser APIs
Clipboard API for one-click copying:
const copyToClipboard = async (text) => {
try {
await navigator.clipboard.writeText(text);
console.log('Copied successfully');
} catch (err) {
console.error('Failed to copy:', err);
}
};
Intersection Observer for lazy loading:
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);
});
The Power of Frameworks
React Hooks simplify state logic reuse:
const useToggle = (initialState = false) => {
const [state, setState] = useState(initialState);
const toggle = () => setState(!state);
return [state, toggle];
};
// Usage
const [isDark, toggleDark] = useToggle(false);
<button onClick={toggleDark}>
{isDark ? 'Switch to Light' : 'Switch to Dark'}
</button>
Vue's Composition API is equally powerful:
import { ref } from 'vue';
export function useCounter(initialValue = 0) {
const count = ref(initialValue);
const increment = () => count.value++;
return { count, increment };
}
// Usage
const { count, increment } = useCounter();
Build Tool Automation
Webpack aliases eliminate long paths:
// webpack.config.js
resolve: {
alias: {
'@': path.resolve(__dirname, 'src/'),
'@components': path.resolve(__dirname, 'src/components/')
}
}
// Usage
import Button from '@/components/Button';
Regular Expressions: The Swiss Army Knife of Text Processing
Regex to extract URL parameters:
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=John&age=25');
// { name: "John", age: "25" }
Applying Design Patterns
Singleton pattern ensures a single global instance:
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
Performance Optimization Techniques
Debounce and throttle implementations:
// Debounce
const debounce = (fn, delay) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
};
// Throttle
const throttle = (fn, delay) => {
let lastTime = 0;
return (...args) => {
const now = Date.now();
if (now - lastTime >= delay) {
fn(...args);
lastTime = now;
}
};
};
Modern CSS Solutions
CSS Grid for Holy Grail layout:
.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; }
The Help of Type Systems
TypeScript generics avoid redundant definitions:
interface Response<T> {
code: number;
data: T;
message: string;
}
// Usage
type UserResponse = Response<{
id: number;
name: string;
}>;
type ProductResponse = Response<{
id: string;
price: number;
}>;
The Art of Immutable Data
Use spread operators to avoid direct mutations:
const user = { name: 'John', age: 25 };
// Update age
const updatedUser = { ...user, age: 26 };
// Add property
const userWithEmail = { ...user, email: 'john@example.com' };
The Elegance of Functional Programming
Chaining array methods:
const users = [
{ id: 1, name: 'John', age: 25, active: true },
{ id: 2, name: 'Jane', 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);
Browser Storage Strategies
LocalStorage wrapper:
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);
}
};
// Usage
storage.set('user', { name: 'John' });
const user = storage.get('user'); // { name: "John" }
Animation Performance Optimization
Use will-change
to hint the browser:
.animated-element {
will-change: transform, opacity;
transition: transform 0.3s ease, opacity 0.3s ease;
}
requestAnimationFrame
for smooth animations:
const animate = () => {
element.style.transform = `translateX(${position}px)`;
position += 1;
if (position < 100) {
requestAnimationFrame(animate);
}
};
requestAnimationFrame(animate);
The Art of Error Handling
Global error catching:
window.addEventListener('error', (event) => {
console.error('Global error:', event.error);
// Report error to server
reportErrorToServer(event.error);
return true; // Prevent default error handling
});
window.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled Promise rejection:', event.reason);
});
Mobile Adaptation Solutions
Viewport meta tag with rem:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
html {
font-size: calc(100vw / 7.5); /* For a 750px design, 1rem = 100px */
}
.box {
width: 1.5rem; /* 150px */
height: 1rem; /* 100px */
}
Code Splitting and Lazy Loading
Dynamic imports for on-demand loading:
const loadModule = async () => {
const module = await import('./heavyModule.js');
module.doSomething();
};
// Lazy loading in React
const LazyComponent = React.lazy(() => import('./HeavyComponent'));
Practical Code Snippets
Generate random ID:
const generateId = () =>
Math.random().toString(36).substr(2, 9);
// Usage
const id = generateId(); // "4f7d8e2b1"
Deep clone objects:
const deepClone = obj => JSON.parse(JSON.stringify(obj));
// More robust solution
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;
};
Debugging Tips
Advanced console usage:
console.table([
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 }
]);
console.time('fetch');
await fetch('https://api.example.com/data');
console.timeEnd('fetch'); // fetch: 256ms
Code Quality Tools
ESLint auto-fix:
eslint --fix src/**/*.js
Prettier for consistent code style:
// .prettierrc
{
"semi": false,
"singleQuote": true,
"printWidth": 80
}
Documentation as Code
JSDoc for API documentation:
/**
* Calculate the sum of two numbers
* @param {number} a - First addend
* @param {number} b - Second addend
* @returns {number} Sum of the two numbers
*/
function add(a, b) {
return a + b;
}
Continuous Integration Automation
Git Hooks to prevent bad commits:
// package.json
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"pre-push": "npm run test"
}
},
"lint-staged": {
"*.js": ["eslint --fix", "git add"]
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn