每位开发者必须知道的21个JavaScript技巧 🚀

3,859 阅读4分钟

JavaScript 是一种强大而灵活的语言,掌握一些实用的小技巧可以让你的代码更简洁、更快速和更高效。以下是21个可以在实际应用中使用的实用 JavaScript 技巧,帮助提升你的开发流程。

  1. 一步完成解构和重命名

    你可以在对象解构时重命名变量,这在存在命名冲突时非常有用。

    const user = { name: 'Alice', age: 25 };
    const { name: userName, age: userAge } = user;
    console.log(userName); // Alice
    console.log(userAge);  // 25
    
  2. 函数调用中的可选链

    可选链可以与函数一起使用,确保在调用函数之前该函数确实存在。

    const user = {
      getName: () => 'Alice',
    };
    console.log(user.getName?.());   // Alice
    console.log(user.getAge?.());    // undefined
    
  3. 使用 ||= 运算符进行默认赋值

    逻辑或赋值(||=)仅在变量为 nullundefined 或假值(如 0)时才会赋值。

    let count;
    count ||= 10;
    console.log(count); // 10
    
  4. 使用 ??= 运算符进行默认赋值

    空值合并赋值(??=)仅在变量为 nullundefined 时才会赋值。

    let count;
    count ??= 10;
    console.log(count); // 10
    

    ??=||= 运算符的主要区别在于它们处理的“假值”的定义不同:

    ??=(空值合并赋值)

    • 仅在变量为 nullundefined 时才会赋值。

    • 适用于需要保留 falsy 值(如 0false'')的场景。

      let value;
      value ??= 10;
      console.log(value); // 10
      ​
      value = 0;
      value ??= 20;
      console.log(value); // 0 (没有被赋值)
      

    ||=(逻辑或赋值)

    • 在变量为 nullundefined 或任何 falsy 值(如 0false'')时才会赋值。

    • 更加严格地检查变量的真值。

      let value;
      value ||= 10;
      console.log(value); // 10
      ​
      value = 0;
      value ||= 20;
      console.log(value); // 20 (被赋值)
      
  5. 使用扩展运算符将 NodeList 转换为数组

    扩展运算符提供了一种快速将 NodeList 转换为数组的方法。

    const divs = document.querySelectorAll('div');
    const divArray = [...divs];
    console.log(Array.isArray(divArray)); // true
    
  6. 带默认值的数组/对象解构

    在解构时为缺失的键分配默认值,以避免出现undefined

    const user = { name: 'Alice' };
    const { name, age = 25 } = user;
    console.log(age); // 25
    
  7. 从数组中移除假值

    使用 filter() 方法从数组中移除假值(如 0nullundefinedfalse)。

    const arr = [0, 'hello', null, 42, false, 'world'];
    const filtered = arr.filter(Boolean);
    console.log(filtered); // ["hello", 42, "world"]
    
  8. 按属性对对象数组进行排序

    轻松地按特定属性对对象数组进行排序。

    const users = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 20 }];
    users.sort((a, b) => a.age - b.age);
    console.log(users); // [{ name: 'Bob', age: 20 }, { name: 'Alice', age: 25 }]
    
  9. 动态导入实现懒加载

    动态导入允许你仅在需要时加载模块,从而减少初始加载时间。

    const loadModule = async () => {
      const module = await import('./myModule.js');
      module.default(); // 调用默认导出的函数
    };
    loadModule();
    
  10. 带对象解构的默认参数

    在使用默认参数时,你还可以解构并为特定属性设置默认值。

    function createUser({ name = 'Guest', age = 18 } = {}) {
      console.log(name, age);
    }
    createUser();               // Guest 18
    createUser({ name: 'Alice' }); // Alice 18
    
  11. 使用 Object.assign() 进行浅拷贝

    Object.assign() 非常适合进行对象的浅拷贝,而不会更改原始对象。

    const original = { a: 1, b: 2 };
    const copy = Object.assign({}, original);
    copy.a = 3;
    console.log(original.a); // 1 (未改变)
    
  12. 记忆函数以提高性能

    缓存技术根据参数保存昂贵函数调用的结果,适用于计算密集型函数。

    const memoize = (fn) => {
      const cache = {};
      return (...args) => {
        const key = JSON.stringify(args);
        if (!cache[key]) {
          cache[key] = fn(...args);
        }
        return cache[key];
      };
    };
    ​
    const slowSquare = (n) => n * n;
    const memoizedSquare = memoize(slowSquare);
    console.log(memoizedSquare(4)); // 16 (在第二次调用时缓存)
    
  13. 使用 reduce 来分组数组项

    reduce() 可以根据某个属性对数组项进行分组,这在数据处理时常常需要。

    const people = [
      { name: 'Alice', role: 'admin' },
      { name: 'Bob', role: 'user' },
      { name: 'Charlie', role: 'admin' },
    ];
    const grouped = people.reduce((acc, person) => {
      (acc[person.role] = acc[person.role] || []).push(person);
      return acc;
    }, {});
    console.log(grouped);
    // { admin: [{ name: 'Alice' }, { name: 'Charlie' }], user: [{ name: 'Bob' }] }
    
  14. 使用 Array.flat(Infinity) 展平嵌套数组

    使用 Array.flat(Infinity) 可以轻松展平多层嵌套数组。

    const nested = [1, [2, [3, [4]]]];
    console.log(nested.flat(Infinity)); // [1, 2, 3, 4]
    
  15. 使用 ! 切换布尔值

    切换布尔值只需使用 NOT 运算符两次即可。

    let isVisible = false;
    isVisible = !isVisible;
    console.log(isVisible); // true
    
  16. 使用 concat() 合并多个数组

    concat() 有助于在一条语句中合并多个数组。

    const arr1 = [1, 2];
    const arr2 = [3, 4];
    const arr3 = [5, 6];
    const merged = arr1.concat(arr2, arr3);
    console.log(merged); // [1, 2, 3, 4, 5, 6]
    
  17. 使用 for...ofawait 进行异步数组迭代

    当迭代一系列 Promise 时, for...ofawait可确保每个 Promise 在下一个 Promise 运行之前解析。

    const fetchData = async () => {
      const urls = ['url1', 'url2'];
      for (const url of urls) {
        const response = await fetch(url);
        console.log(await response.json());
      }
    };
    
  18. 快速获取数组中的最后一项

    在不知道数组长度的情况下,快速获取数组中的最后一项。

    const arr = [1, 2, 3, 4];
    console.log(arr.at(-1)); // 4
    
  19. 使用 Intl 进行日期格式化

    Intl.DateTimeFormat 提供了一种强大的方式来按地区格式化日期。

    const date = new Date();
    const formatted = new Intl.DateTimeFormat('en-GB', {
      dateStyle: 'full',
    }).format(date);
    console.log(formatted); // 例如:"Monday, 25 October 2021"
    
  20. 使用 Math.round() 和模板字面量进行数字四舍五入

    模板字面量可以直接格式化四舍五入的数字。

    const num = 3.14159;
    console.log(`${Math.round(num * 100) / 100}`); // 3.14
    
  21. 使用 Array.from() 将类数组对象转换为数组

    使用 Array.from() 可以将类数组对象(例如 arguments)转换为真正的数组。

    function example() {
      const argsArray = Array.from(arguments);
      console.log(argsArray);
    }
    example(1, 2, 3); // [1, 2, 3]
    

这些技巧简化了 JavaScript 中常见的编码模式。将它们融入你的工作流程中,可以编写出既高效又富有表现力的代码。