前端代码追求极致的优化
javascript书写方式
数组
// good
const array = [1, 2, 3];
// not use
const array = new Array(3);
array[0] = 1;
array[1] = 2;
array[2] = 3;
乘除运算
// good
const a = num >> 1;
// not use
const a = num / 2;
// good
const a = num << 1;
// not use
const a = num * 2;
拥抱箭头函数
// good
const add = (a, b) => a + b;
// not use
function add(a, b) {
return a + b;
}
处理默认参数
// good
function greet(name = 'Guest') {
console.log(`Hello, ${name}!`);
}
// not use
function greet(name) {
name = name || 'Guest';
console.log('Hello, ' + name + '!');
}
字符串的拼接
// good
const name = 'Alice';
console.log(`Hello, ${name}!`);
// not use
const name = 'Alice';
console.log('Hello, ' + name + '!');
对象解构
// good
const person = { name: 'John', age: 30 };
const { name, age } = person;
// not use
const person = { name: 'John', age: 30 };
const name = person.name;
const age = person.age;
使用map()进行数组转换
// good
const numbers = [1, 2, 3];
const squaredNumbers = numbers.map(number => number * number);
// not use
const numbers = [1, 2, 3];
const squaredNumbers = [];
for (let i = 0; i < numbers.length; i++) {
squaredNumbers.push(numbers[i] * numbers[i]);
}
使用 Promise 处理异步操作
// good
async function fetchData() {
try {
const data = await fetch('https://api.example.com/data');
console.log(data);
} catch (error) {
console.error(error);
}
}
fetchData();
// not use
function fetchData() {
return new Promise((resolve, reject) => {
// Asynchronous operation
if (success) {
resolve(data);
} else {
reject(error);
}
});
}
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
性能优化记忆-适用于递归函数和重复计算场景
// good
function memoize(func) {
const cache = {};
return function(n) {
if (n in cache) {
return cache[n];
} else {
const result = func(n);
cache[n] = result;
return result;
}
};
}
const memoizedFactorial = memoize(function factorial(num) {
if (num === 0) {
return 1;
} else {
return num * memoizedFactorial(num - 1);
}
});
// not use
function factorial(num) {
if (num === 0) {
return 1;
} else {
return num * factorial(num - 1);
}
}
注释:
- memoize函数创建了一个缓存对象cache。当memoizedFactorial函数被调用时,它首先检查缓存中是否已经有了计算结果。如果有,就直接返回结果;如果没有,就进行计算,并将结果存入缓存。
处理多种条件选择
// good
const value = 3;
const result = value === 1 ? 'One' : value === 2 ? 'Two' : 'Other';
// not use
const value = 3;
let result;
if (value === 1) {
result = 'One';
} else if (value === 2) {
result = 'Two';
} else {
result = 'Other';
}
集合去重
// good
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)];
// not use
const uniqueNumbers = [];
const numbers = [1, 2, 2, 3, 4, 4, 5];
for (let i = 0; i < numbers.length; i++) {
if (!uniqueNumbers.includes(numbers[i])) {
uniqueNumbers.push(numbers[i]);
}
}
使用bind()函数处理this指向
// good
function greet() {
console.log('Hello, ' + this.name + '!');
}
const person = { name: 'Alice' };
const boundGreet = greet.bind(person);
boundGreet();
// not use
function greet() {
console.log('Hello, ' + this.name + '!');
}
const person = { name: 'Alice' };
const boundGreet = function() {
greet.call(person);
}
boundGreet()
使用 Object.assign() 进行对象合并
// good
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = Object.assign({}, obj1, obj2);
// not use
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = {};
for (let key in obj1) {
merged[key] = obj1[key];
}
for (let key in obj2) {
merged[key] = obj2[key];
}
使用 Array.from() 进行映射和过滤
// good
const numbers = [1, 2, 3, 4, 5];
const evenSquaredNumbers = Array.from(numbers, number => number * number).filter(number => number % 2 === 0);
// not use
const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(number => number * number);
const evenSquaredNumbers = squaredNumbers.filter(number => number % 2 === 0);
注释:
- Array.from()不仅创建了一个新数组,还允许在创建数组的同时对每个元素应用映射函数。然后,可以直接在结果上应用filter(),从而避免了创建中间数组。
- 使用map()和filter()的方法虽然易于理解,但可能会导致生成中间数组,从而降低代码效率。
使用剩余参数
// good
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
// not use
function sum(a, b) {
const numbers = [a, b];
return numbers.reduce((total, num) => total + num, 0);
}
优化循环
// good
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map(number => number * 2);
// not use
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = [];
for (let i = 0; i < numbers.length; i++) {
doubledNumbers.push(numbers[i] * 2);
}
使用 Array.prototype.reduce() 进行复杂操作
// good
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((total, num) => total + num, 0);
// not use
const numbers = [1, 2, 3, 4, 5];
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
处理日期和时间
// good
const now = new Date();
const [year, month, day] = [now.getFullYear(), now.getMonth() + 1, now.getDate()];
// not use
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1; // 月份从0开始,所以需要加1
const day = now.getDate();
使用 JSON 数据
// good
const jsonData = '{"name": "John", "age": 30}';
try {
const parsedData = JSON.parse(jsonData);
console.log(parsedData.name); // 输出: 'John'
} catch (error) {
console.error('Invalid JSON data:', error);
}
// not use
const jsonData = '{"name": "John", "age": 30}';
const parsedData = JSON.parse(jsonData);
console.log(parsedData.name); // 输出: 'John'
使用模块进行代码组织
// greetings.js
export function greet(name) {
console.log('Hello, ' + name + '!');
}
// calculations.js
export function calculateSquare(num) {
return num * num;
}
// main.js
import { greet } from './greetings';
import { calculateSquare } from './calculations';
greet('Alice');
console.log(calculateSquare(3));