前端代码追求极致的优化

67 阅读3分钟

前端代码追求极致的优化

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));