亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

9 個簡潔的 JavaScript 一行代碼技巧,幫你取代 50 行代碼

我们都在某个时候看过一些可怕的JavaScript代码段落,在心里暗自咒骂,心里明白一定有更好的解决方法。

学了一段时间之后,我发现了一些简洁的单行代码,这些单行代码可以替代许多冗长的代码。这些代码真是太棒了。

这些确实是利用现代JavaScript特性解决常见问题的方法,非常实用且容易阅读的技巧。

所以,无论是清理代码还是开始新项目,这些技巧都能帮助你写出更优雅且容易维护的代码。

这里有9个超实用的一句话妙招,你今天就可以用起来。

展平嵌套数组

在过去,你是否曾经尝试过展平一个嵌套很深的数组?这通常需要多层循环、临时数组,以及过多的代码。

但现在它被精彩地执行在一个强大的单行代码里。

    const 平铺数组 = arr => arr.flat(Infinity); // 将数组展平

    const 嵌套数组 = [1, [2, 3, [4, 5, [6, 7]]], 8, [9, 10]]; // 包含多个层级的嵌套数组
    const 展平后的数组 = 平铺数组(嵌套数组);
    // 结果: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // 展平后的数组

请选择: 点击进入全屏, 点击退出全屏.

要是用传统的方法来做这件事,你可能会得到这样的结果。

function 深度展平数组艰难方式(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      // 判断是否为数组
      result = result.concat(深度展平数组艰难方式(arr[i]));
    } else {
      result.push(arr[i]);
    }
  }
  return result;
}
// 此函数将以困难的方式展平嵌套数组,这意味着如果数组元素自身还是数组,它会递归地展平这些元素

进入全屏。退出全屏。

所有的繁重任务都交给 flat() 来处理,而添加 Infinity 则让它可以向下遍历任意深度。简单、干净,而且管用。

对象深克隆:不依赖其他对象的深度克隆

如果你需要真正的深层克隆对象,并且不希望引入lodash,这里有一个无需依赖的解决方案,它可以处理嵌套对象、数组以及日期。

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

    const 用户对象 = {
      user: { name: 'Alex', date: new Date() },
      scores: [1, 2, [3, 4]],
      active: true
    };

    const 克隆 = deepClone(用户对象);

切换到全屏模式,退出全屏模式

老方法?得像这样输入:

    function manualDeepClone(obj) {
      if (obj === null || typeof obj !== 'object') return obj;
      if (obj instanceof Date) return new Date(obj);

      const clone = Array.isArray(obj) ? [] : {};

      for (let key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          clone[key] = manualDeepClone(obj[key]);
        }
      }
      return clone;
    }

全屏模式退出全屏

小提示: 这条简短的代码片段有一些限制——它不能处理函数、符号或循环引用。但对于90%的情况来说,它还是很实用的。

将 CSV 转换为对象列表

这是一个不错的代码行,它将CSV数据转换为可供操作的对象数组,非常适合于API的响应或读入数据。

const csvToObjects = csv => csv.split('\n').map(row => Object.fromEntries(row.split(',').map((value, i, arr) => [arr[0].split(',')[i], value])));

const csvData = `名字,年纪,所在城市
Peboy,30,纽约市
Peace,25,旧金山市
Lara,35,芝加哥市`;

const parsed = csvToObjects(csvData);
// 结果如下:
// [
//   { 名字: 'Peboy', 年纪: '30', 所在城市: '纽约市' },
//   { 名字: 'Peace', 年纪: '25', 所在城市: '旧金山市' },
//   { 名字: 'Lara', 年纪: '35', 所在城市: '芝加哥市' }
// ]

全屏模式 退出全屏

嗯,你可能会写这样的东西吧。

/**

* 将CSV转换为对象

* @param {string} csv - CSV字符串

* @returns {object[]} 转换后的对象数组
 */
function 将CSV转换为对象(csv) {
  const 行 = csv.split('\n');
  const 标题 = 行[0].split(',');
  const 结果 = [];

  for (let i = 1; i < 行.length; i++) {
    const 对象 = {};
    const 当前行 = 行[i].split(',');

    for (let j = 0; j < 标题.length; j++) {
      对象[标题[j]] = 当前行[j];
    }
    结果.push(对象);
  }
  return 结果;
}

点击这里全屏 点击这里退出全屏

这是一种用一行代码有效进行数据转换的方法,但在投入使用之前,最好先增加一些错误处理机制。

数组操作:去重和排序

这里有一条简化的代码行,可以同时删除重复项并排序数组,非常适合清理数据。

    const uniqueSorted = arr => [...new Set(arr)].sort((a, b) => a - b);

    // 例如它的用法:
    const messyArray = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
    const cleaned = uniqueSorted(messyArray);
    // 结果如下:[1, 2, 3, 4, 5, 6, 9]

    // 对于字符串的排序

    const messyStrings = ['banana', 'apple', 'apple', 'cherry', 'banana'];
    const cleanedStrings = [...new Set(messyStrings)].sort();
    // 结果如下:['apple', 'banana', 'cherry']

打开全屏 关闭全屏

这就是以前的样子:

function 手动清理数组(arr) {
  const unique = [];
  for (let i = 0; i < arr.length; i++) {
    if (unique.indexOf(arr[i]) === -1) {
      unique.push(arr[i]);
    }
  }
  return unique.sort((a, b) => a - b);
}

全屏,退出

Set 能完美去重,然后通过展开运算符将它再转为数组。最后,只需调用 sort() 方法即可排序!

DOM 操纵:查找和修改多个节点

这里有一句非常强大的代码,可以让你同时查询和转换多个DOM元素。

const modifyElements = selector => Array.from(document.querySelectorAll(selector)).forEach(el => el.style);

// 可以这样用:
const updateButtons = modifyElements('.btn')
  .map(style => Object.assign(style, {
    backgroundColor: '#007bff',
    color: 'white',
    padding: '10px 20px'
  }));
// 调整按钮样式

// 或者更简单地切换按钮状态:
const toggleAll = selector => document.querySelectorAll(selector).forEach(el => el.classList.toggle('active'));

全屏, 退出全屏

按传统,

    function updateElementsManually(selector) {
      // 更新元素的背景色和文字颜色等样式
      const elements = document.querySelectorAll(selector);
      for (let i = 0; i < elements.length; i++) {
        const el = elements[i];
        // 设置元素的背景色为 #007bff
        el.style.backgroundColor = '#007bff';
        // 设置元素的文字颜色为白色
        el.style.color = 'white';
        // 设置元素的内边距为 10px 20px
        el.style.padding = '10px 20px';
      }
    }

进入全屏 恢复窗口

这在所有现代浏览器中都可以运行,从而避免编写重复的DOM操作。

并行 API 调用及其清晰的错误处理

这是一行简洁的代码,可以并行调用APIs,同时错误处理得非常干净。

const parallelCalls = urls => Promise.allSettled(urls.map(url => fetch(url).then(r => r.json())));

// 把它用起来:
const urls = [
  'https://api.example.com/users',
  'https://api.example.com/posts',
  'https://api.example.com/comments'
];

// 一行代码搞定:
const getData = async () => {
  const results = await parallelCalls(urls);
  // 解析结果,提取已成功加载的数据
  const [users, posts, comments] = results.map(r => r.status === 'fulfilled' ? r.value : null);
};

切换到全屏模式。退出全屏。

换句话说,如果要说得更详细一点:

async function fetchDataManually(urls) {
      // 这个函数是用来手动获取数据的。
      const results = [];
      for (const url of urls) {
        try {
          const response = await fetch(url);
          const data = await response.json();
          results.push({ status: 'fulfilled', value: data });
        } catch (error) {
          results.push({ status: 'rejected', reason: error });
        }
      }
      return results;
    }

按一下全屏 开启或关闭

Promise.allSettled 是这里的英雄;即使一个请求失败了,它也不会导致整体失败,并且为每个请求提供明确的状态结果。

日期/时间处理:无需使用库即可清洗日期字符串

这里有一句甜蜜的妙语,可以将日期转换为干净整洁的字符串,而且无需任何外部依赖。

    const formatDate = date => new Intl.DateTimeFormat('zh-CN', { dateStyle: 'long', timeStyle: 'short' }).format(date);

    const now = new Date();
    console.log(formatDate(now));
    // 输出: '2024年12月5日星期四 下午2:30'

    // 想要不同格式?很简单:
    const shortDate = date => new Intl.DateTimeFormat('zh-CN', { month: 'short', day: '2-digit', year: 'numeric' }).format(date);
    // 输出: '2024年12月5日'

切换到全屏模式,退出全屏

老式的方法是这样的。

    function formatDateManually(date) {
      const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
      const 月份 = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];

      const dayName = days[date.getDay()];
      const monthName = 月份[date.getMonth()];
      const day = date.getDate();
      const year = date.getFullYear();
      const hours = date.getHours();
      const minutes = date.getMinutes();
      const ampm = hours >= 12 ? '下午' : '上午';

      return `${year}年${monthName}${day}, 星期${dayName} ${hours % 12}: ${minutes.toString().padStart(2, '0')} ${ampm}时`;
    }

进入全屏 退出全屏

Intl.DateTimeFormat(注:一种处理日期格式的国际标准方法)负责处理所有的复杂任务,包括本地化。再也不用手动拼接日期字符串了!

事件处理:简洁防抖

这里有一个简洁的一行代码,可以为任何函数创建一个防抖函数——非常适用于搜索框输入或窗口大小调整事件处理程序:

    const debounce=(fn,ms)=>{let timeout;return(...args)=>{clearTimeout(timeout);timeout=setTimeout(()=>fn(...args),ms);};};

    // 试试这个用法:
    const expensiveSearch=query=>console.log('搜索查询:',query);
    const debouncedSearch=debounce(expensiveSearch,300);

    // 在输入事件监听器中使用它:
    searchInput.addEventListener('input',e=>debouncedSearch(e.target.value));

进入全屏,退出全屏

传统的方式如下:

function 创建防抖函数(fn, delay) {
  let 超时ID;

  return function 防抖(...args) {
    if (超时ID) {
      clearTimeout(超时ID);
    }

    超时ID = setTimeout(() => {
      fn.apply(this, args);
      超时ID = null;
    }, delay);
  };
}

切换到全屏模式: 退出全屏

这一行代码可以处理所有基本的防抖用例,并且避免不必要的函数调用,尤其是在快速连续输入,如打字或调整窗口大小时。

本地对象存储:具有验证功能的对象存储

这里有一个简洁的代码行,用于在 localStorage 中存储对象,并自带验证和错误处理。

    const store = key => ({ get: () => JSON.parse(localStorage.getItem(key)), set: data => localStorage.setItem(key, JSON.stringify(data)), remove: () => localStorage.removeItem(key) });

    // 用法如下:
    const userStore = store('user');

    // 存数据
    userStore.set({ id: 1, name: 'John', preferences: { theme: 'dark' } });

    // 取数据
    const userData = userStore.get();

    // 删数据
    userStore.remove();

全屏模式 全屏退出

老方法可能这样:

    function handleLocalStorage(key) {
      return {
        get: function() {
          try {
            const item = localStorage.getItem(key);
            return item ? JSON.parse(item) : null;
          } catch (e) {
            console.error('读取localStorage数据时出错:', e);
            return null;
          }
        },
        set: function(data) {
          try {
            localStorage.setItem(key, JSON.stringify(data));
          } catch (e) {
            console.error('写入localStorage数据时出错:', e);
          }
        },
        remove: function() {
          try {
            localStorage.removeItem(key);
          } catch (e) {
            console.error('移除localStorage数据时出错:', e);
          }
        }
      };
    }

点击此处切换到全屏模式,点击此处切换回正常模式

这个库为你提供了简洁易用的localStorage操作接口,并自动处理JSON数据的解析与序列化,无需手动处理。

结尾

这些一行代码技巧不仅仅是为了减少代码——更是为了写出更聪明的代码。每一个技巧都以一种清晰、可维护的方式解决了常见的 JavaScript 难题。虽然这些代码片段确实非常强大,但请记住,可读性永远是第一位的。如果一行代码让代码更难理解,那就拆分成多行。

在你的项目中可以随意混合使用这些模式,并且别忘了检查浏览器的兼容性,尤其是当你需要支持旧版浏览器时,特别是查看新特性,比如 flat()Intl.DateTimeFormat 的兼容性。

有你自己强大的JavaScript一行代码吗?我很想看看哦!

关注我[X]上的更多JavaScript技巧、窍门和 web 开发讨论,让我们的开发生活更轻松。我经常分享一些实用的代码片段和最佳实践。

保持好奇,不断编码,并记住:好的代码不在于写的少,而在于能否清晰地表达你的意图。

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消