漫步白月光工具站
获取源码
切换模式
收藏列表
放到桌面
工具搜索
用户登陆
QQ技术交流群二维码

技术交流群

开发者技术讨论与问题解答,分享最新技术动态

群号: 827253120
QQ用户交流群二维码

用户交流群

产品使用反馈与交流,获取最新产品资讯

群号: 876127697
扫码即可加入

Array/数组

将值转换为数组

const castArray = (value) => (Array.isArray(value) ? value : [value]);

// Examples
castArray(1); // [1]
castArray([1, 2, 3]); // [1, 2, 3]

检查数组是否为空

// `arr` is an array
const isEmpty = (arr) => !Array.isArray(arr) || arr.length === 0;

// Examples
isEmpty([]); // true
isEmpty([1, 2, 3]); // false

克隆数组

// `arr` is an array
const clone = (arr) => arr.slice(0);

// Or
const clone = (arr) => [...arr];

// Or
const clone = (arr) => Array.from(arr);

// Or
const clone = (arr) => arr.map((x) => x);

// Or
const clone = (arr) => JSON.parse(JSON.stringify(arr));

// Or
const clone = (arr) => arr.concat([]);

比较两个数组,而不考虑顺序

// `a` and `b` are arrays
const isEqual = (a, b) => JSON.stringify(a.sort()) === JSON.stringify(b.sort());

// Examples
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, 3, 2]); // true
isEqual([1, 2, 3], [1, "2", 3]); // false

比较两个数组

// `a` and `b` are arrays
const isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);

// Or
const isEqual = (a, b) =>
  a.length === b.length && a.every((v, i) => v === b[i]);

// Examples
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, "2", 3]); // false

将对象数组转换为单个对象

const toObject = (arr, key) =>
  arr.reduce((a, b) => ({ ...a, [b[key]]: b }), {});

// Example
toObject(
  [
    { id: "1", name: "Alpha", gender: "Male" },
    { id: "2", name: "Bravo", gender: "Male" },
    { id: "3", name: "Charlie", gender: "Female" },
  ],
  "id"
);
/* 
{
    '1': { id: '1', name: 'Alpha', gender: 'Male' },
    '2': { id: '2', name: 'Bravo', gender: 'Male' },
    '3': { id: '3', name: 'Charlie', gender: 'Female' },
}
*/

将字符串数组转换为数字

const toNumbers = (arr) => arr.map(Number);

// Or
const toNumbers = (arr) => arr.map((x) => +x);

// Example
toNumbers(["2", "3", "4"]); // [2, 3, 4]

通过对象数组的属性进行计数

const countBy = (arr, prop) =>
  arr.reduce(
    (prev, curr) => ((prev[curr[prop]] = ++prev[curr[prop]] || 1), prev),
    {}
  );

// Example
countBy(
  [
    { branch: "audi", model: "q8", year: "2019" },
    { branch: "audi", model: "rs7", year: "2020" },
    { branch: "ford", model: "mustang", year: "2019" },
    { branch: "ford", model: "explorer", year: "2020" },
    { branch: "bmw", model: "x7", year: "2020" },
  ],
  "branch"
);

// { 'audi': 2, 'ford': 2, 'bmw': 1 }

计算数组中某个值的出现

const countOccurrences = (arr, val) =>
  arr.reduce((a, v) => (v === val ? a + 1 : a), 0);

// Or
const countOccurrences = (arr, val) =>
  arr.filter((item) => item === val).length;

// Examples
countOccurrences([2, 1, 3, 3, 2, 3], 2); // 2
countOccurrences(["a", "b", "a", "c", "a", "b"], "a"); // 3

计算数组元素的出现

const countOccurrences = (arr) =>
  arr.reduce((prev, curr) => ((prev[curr] = ++prev[curr] || 1), prev), {});

// Examples
countOccurrences([2, 1, 3, 3, 2, 3]); // { '1': 1, '2': 2, '3': 3 }
countOccurrences(["a", "b", "a", "c", "a", "b"]); // { 'a': 3, 'b': 2, 'c': 1 }

创建一个累加和数组

const accumulate = (arr) =>
  arr.map(
    (
      (sum) => (value) =>
        (sum += value)
    )(0)
  );

// Or
const accumulate = (arr) =>
  arr.reduce((a, b, i) => (i === 0 ? [b] : [...a, b + a[i - 1]]), []);

// Or
const accumulate = (arr) =>
  arr.reduce((a, b, i) => (i === 0 ? [b] : [...a, b + a[i - 1]]), 0);

// Example
accumulate([1, 2, 3, 4]); // [1, 3, 6, 10]
// 1             = 1
// 1 + 2         = 3
// 1 + 2 + 3     = 6
// 1 + 2 + 3 + 4 = 10

在给定范围内创建一个数字数组

const range = (min, max) =>
  [...Array(max - min + 1).keys()].map((i) => i + min);

// Or
const range = (min, max) =>
  Array(max - min + 1)
    .fill(0)
    .map((_, i) => min + i);

// Or
const range = (min, max) =>
  Array.from({ length: max - min + 1 }, (_, i) => min + i);

// Example
range(5, 10); // [5, 6, 7, 8, 9, 10]

创建笛卡尔积

const cartesian = (...sets) =>
  sets.reduce(
    (acc, set) => acc.flatMap((x) => set.map((y) => [...x, y])),
    [[]]
  );

// Example
cartesian([1, 2], [3, 4]); // [ [1, 3], [1, 4], [2, 3], [2, 4] ]

/*
       3       4
   ---------------
1 | [1, 3]  [1, 4]
  |
2 | [2, 3]  [2, 4]

*/

清空数组

const empty = (arr) => (arr.length = 0);

// Or
arr = [];

从数组中找到最接近的数字

// Find the number from `arr` which is closest to `n`
const closest = (arr, n) =>
  arr.reduce((prev, curr) =>
    Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev
  );

// Or
const closest = (arr, n) =>
  arr.sort((a, b) => Math.abs(a - n) - Math.abs(b - n))[0];

// Example
closest([29, 87, 8, 78, 97, 20, 75, 33, 24, 17], 50); // 33

查找数组中最后一个匹配项的索引

const lastIndex = (arr, predicate) =>
  arr.reduce((prev, curr, index) => (predicate(curr) ? index : prev), -1);

// Or
const lastIndex = (arr, predicate) =>
  arr.map((item) => predicate(item)).lastIndexOf(true);

// Example
lastIndex([1, 3, 5, 7, 9, 2, 4, 6, 8], (i) => i % 2 === 1); // 4
lastIndex([1, 3, 5, 7, 9, 8, 6, 4, 2], (i) => i > 6); // 5

查找数组中最大项的索引

const indexOfMax = (arr) =>
  arr.reduce((prev, curr, i, a) => (curr > a[prev] ? i : prev), 0);

// Examples
indexOfMax([1, 3, 9, 7, 5]); // 2
indexOfMax([1, 3, 7, 7, 5]); // 2

查找数组最小项的索引

const indexOfMin = (arr) =>
  arr.reduce((prev, curr, i, a) => (curr < a[prev] ? i : prev), 0);

// Examples
indexOfMin([6, 4, 8, 2, 10]); // 3
indexOfMin([6, 4, 2, 2, 10]); // 2

查找数组中最长字符串的长度

const findLongest = (words) => Math.max(...words.map((el) => el.length));

// Example
findLongest(["always", "look", "on", "the", "bright", "side", "of", "life"]); // 6

通过给定键找到数组的最大项

const maxBy = (arr, key) =>
  arr.reduce((a, b) => (a[key] >= b[key] ? a : b), {});

// Example
const people = [
  { name: "Bar", age: 24 },
  { name: "Baz", age: 32 },
  { name: "Foo", age: 42 },
  { name: "Fuzz", age: 36 },
];
maxBy(people, "age"); // { name: 'Foo', age: 42 }

查找数组的最大项

const max = (arr) => Math.max(...arr);

通过给定键找到数组的最小项

const minBy = (arr, key) => arr.reduce((a, b) => (a[key] < b[key] ? a : b), {});

// Example
const people = [
  { name: "Bar", age: 24 },
  { name: "Baz", age: 32 },
  { name: "Foo", age: 42 },
  { name: "Fuzz", age: 36 },
];
minBy(people, "age"); // { name: 'Bar', age: 24 }

查找数组的最小项

const min = (arr) => Math.min(...arr);

展平数组

const flat = (arr) =>
  [].concat.apply(
    [],
    arr.map((a) => (Array.isArray(a) ? flat(a) : a))
  );
// Or
const flat = (arr) =>
  arr.reduce((a, b) => (Array.isArray(b) ? [...a, ...flat(b)] : [...a, b]), []);

// Or
// See the browser compatibility at https://caniuse.com/#feat=array-flat
const flat = (arr) => arr.flat();

// Example
flat(["cat", ["lion", "tiger"]]); // ['cat', 'lion', 'tiger']

获取所有连续元素的数组

const getConsecutiveArrays = (arr, size) =>
  size > arr.length
    ? []
    : arr.slice(size - 1).map((_, i) => arr.slice(i, size + i));

// Examples
getConsecutiveArrays([1, 2, 3, 4, 5], 2); // [[1, 2], [2, 3], [3, 4], [4, 5]]
getConsecutiveArrays([1, 2, 3, 4, 5], 3); // [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
getConsecutiveArrays([1, 2, 3, 4, 5], 6); // []

获取数组的所有n项

const getNthItems = (arr, nth) => arr.filter((_, i) => i % nth === nth - 1);

// Examples
getNthItems([1, 2, 3, 4, 5, 6, 7, 8, 9], 2); // [2, 4, 6, 8]
getNthItems([1, 2, 3, 4, 5, 6, 7, 8, 9], 3); // [3, 6, 9]

获取数组的所有子集

const getSubsets = (arr) =>
  arr.reduce(
    (prev, curr) => prev.concat(prev.map((k) => k.concat(curr))),
    [[]]
  );

// Examples
getSubsets([1, 2]); // [[], [1], [2], [1, 2]]
getSubsets([1, 2, 3]); // [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

获取数组中值的索引

const indices = (arr, value) =>
  arr.reduce((acc, v, i) => (v === value ? [...acc, i] : acc), []);

// Or
const indices = (arr, value) =>
  arr.map((v, i) => (v === value ? i : false)).filter(Boolean);

// Examples
indices(["h", "e", "l", "l", "o"], "l"); // [2, 3]
indices(["h", "e", "l", "l", "o"], "w"); // []

获取数组的平均值

const average = (arr) => arr.reduce((a, b) => a + b, 0) / arr.length;

获取数组的交集

const getIntersection = (a, ...arr) =>
  [...new Set(a)].filter((v) => arr.every((b) => b.includes(v)));

// Examples
getIntersection([1, 2, 3], [2, 3, 4, 5]); // [2, 3]
getIntersection([1, 2, 3], [2, 3, 4, 5], [1, 3, 5]); // [3]

获取一个数字数组的等级

const ranking = (arr) =>
  arr.map((x, y, z) => z.filter((w) => w > x).length + 1);

// Examples
ranking([80, 65, 90, 50]); // [2, 3, 1, 4]
ranking([80, 80, 70, 50]); // [1, 1, 3, 4]
ranking([80, 80, 80, 50]); // [1, 1, 1, 4]

获得一个数字数组的和

const sum = (arr) => arr.reduce((a, b) => a + b, 0);

获取数组的唯一值

const unique = (arr) => [...new Set(arr)];

// Or
const unique = (arr) => arr.filter((el, i, array) => array.indexOf(el) === i);

// Or
const unique = (arr) =>
  arr.reduce((acc, el) => (acc.includes(el) ? acc : [...acc, el]), []);

获得数组的并集

const union = (...arr) => [...new Set(arr.flat())];

// Example
union([1, 2], [2, 3], [3]); // [1, 2, 3]

通过键将对象数组进行分组

const groupBy = (arr, key) =>
  arr.reduce(
    (acc, item) => ((acc[item[key]] = [...(acc[item[key]] || []), item]), acc),
    {}
  );

// Example
groupBy(
  [
    { branch: "audi", model: "q8", year: "2019" },
    { branch: "audi", model: "rs7", year: "2020" },
    { branch: "ford", model: "mustang", year: "2019" },
    { branch: "ford", model: "explorer", year: "2020" },
    { branch: "bmw", model: "x7", year: "2020" },
  ],
  "branch"
);

/*
{
    audi: [
        { branch: 'audi', model: 'q8', year: '2019' },
        { branch: 'audi', model: 'rs7', year: '2020' }
    ],
    bmw: [
        { branch: 'bmw', model: 'x7', year: '2020' }
    ],
    ford: [
        { branch: 'ford', model: 'mustang', year: '2019' },
        { branch: 'ford', model: 'explorer', year: '2020' }
    ],
}
*/

合并两个数组

// Merge but don't remove the duplications
const merge = (a, b) => a.concat(b);
// Or
const merge = (a, b) => [...a, ...b];

// Merge and remove the duplications
const merge = [...new Set(a.concat(b))];
// Or
const merge = [...new Set([...a, ...b])];

根据条件对数组进行分区

const partition = (arr, criteria) =>
  arr.reduce((acc, i) => (acc[criteria(i) ? 0 : 1].push(i), acc), [[], []]);

// Example
partition([1, 2, 3, 4, 5], (n) => n % 2); // [[2, 4], [1, 3, 5]]

删除数组中的重复值

const removeDuplicate = (arr) =>
  arr.filter((i) => arr.indexOf(i) === arr.lastIndexOf(i));

// Example
removeDuplicate(["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]); //  ['h', 'e', 'w', 'r', 'd']

从数组中删除虚假值

const removeFalsy = (arr) => arr.filter(Boolean);

// Example
removeFalsy([
  0,
  "a string",
  "",
  NaN,
  true,
  5,
  undefined,
  "another string",
  false,
]); // ['a string', true, 5, 'another string']

随机排列数组

const shuffle = (arr) =>
  arr
    .map((a) => ({ sort: Math.random(), value: a }))
    .sort((a, b) => a.sort - b.sort)
    .map((a) => a.value);

// Or
const shuffle = (arr) => arr.sort(() => 0.5 - Math.random());

// Example
shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); // [9, 1, 10, 6, 8, 5, 2, 3, 7, 4]

按给定键对项目数组进行排序

const sortBy = (arr, k) =>
  arr.concat().sort((a, b) => (a[k] > b[k] ? 1 : a[k] < b[k] ? -1 : 0));

// Example
const people = [
  { name: "Foo", age: 42 },
  { name: "Bar", age: 24 },
  { name: "Fuzz", age: 36 },
  { name: "Baz", age: 32 },
];
sortBy(people, "age");

// returns
//  [
//      { name: 'Bar', age: 24 },
//      { name: 'Baz', age: 32 },
//      { name: 'Fuzz', age: 36 },
//      { name: 'Foo', age: 42 },
//  ]

对数字数组进行排序

const sort = (arr) => arr.sort((a, b) => a - b);

// Example
sort([1, 5, 2, 4, 3]); // [1, 2, 3, 4, 5]

将数组拆分为块

const chunk = (arr, size) =>
  arr.reduce(
    (acc, e, i) => (
      i % size ? acc[acc.length - 1].push(e) : acc.push([e]), acc
    ),
    []
  );

// Examples
chunk([1, 2, 3, 4, 5, 6, 7, 8], 3); // [[1, 2, 3], [4, 5, 6], [7, 8]]
chunk([1, 2, 3, 4, 5, 6, 7, 8], 4); // [[1, 2, 3, 4], [5, 6, 7, 8]]

交换矩阵的行和列

const transpose = (matrix) =>
  matrix[0].map((col, i) => matrix.map((row) => row[i]));

// Or
const transpose = (matrix) =>
  matrix[0].map((col, c) => matrix.map((row, r) => matrix[r][c]));

// Or
const transpose = (matrix) =>
  matrix.reduce(
    (prev, next) => next.map((item, i) => (prev[i] || []).concat(next[i])),
    []
  );

// Example
transpose([
  // [
  [1, 2, 3], //      [1, 4, 7],
  [4, 5, 6], //      [2, 5, 8],
  [7, 8, 9], //      [3, 6, 9],
]); //  ]

交换两个数组项

// `i` must be less than `j`
const swapItems = (a, i, j) =>
  (a[i] &&
    a[j] && [
      ...a.slice(0, i),
      a[j],
      ...a.slice(i + 1, j),
      a[i],
      ...a.slice(j + 1),
    ]) ||
  a;

// Example
swapItems([1, 2, 3, 4, 5], 1, 4); // [1, 5, 3, 4, 2]

解压缩数组的数组

const unzip = (arr) =>
  arr.reduce(
    (acc, c) => (c.forEach((v, i) => acc[i].push(v)), acc),
    Array.from({ length: Math.max(...arr.map((a) => a.length)) }, (_) => [])
  );

// Example
unzip([
  ["a", 1],
  ["b", 2],
  ["c", 3],
  ["d", 4],
  ["e", 5],
]); // [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5]]

/*
    a     1
     b   2
      c 3
      d 4
      e 5
*/

压缩多个数组

const zip = (...arr) =>
  Array.from({ length: Math.max(...arr.map((a) => a.length)) }, (_, i) =>
    arr.map((a) => a[i])
  );

// Example
zip(["a", "b", "c", "d", "e"], [1, 2, 3, 4, 5]); // [['a', 1], ['b', 2], ['c', 3], ['d', 4], ['e', 5]]

/*
Does it look like a zipper?
        a 1
        b 2
       c   3
      d     4
     e       5
*/

DOM/元素

检查一个元素是否是另一个元素的后代

const isDescendant = (child, parent) => parent.contains(child);

检查一个元素是否聚焦

const hasFocus = (ele) => ele === document.activeElement;

检查是否支持触摸事件

const touchSupported = () =>
  "ontouchstart" in window ||
  (window.DocumentTouch && document instanceof window.DocumentTouch);

检查用户是否滚动到页面底部

const isAtBottom = () =>
  document.documentElement.clientHeight + window.scrollY >=
  document.documentElement.scrollHeight;

检测Internet Explorer浏览器

const isIE = !!document.documentMode;

检测macOS浏览器

const isMacBrowser = /Mac|iPod|iPhone|iPad/.test(navigator.platform);

获取元素的所有同级

const siblings = (ele) =>
  [].slice.call(ele.parentNode.children).filter((child) => child !== ele);

获取元素相对于文档的位置

const getPosition = (ele) => (
  (r = ele.getBoundingClientRect()),
  { left: r.left + window.scrollX, top: r.top + window.scrollY }
);

// Example
getPosition(document.body); // { left: 0, top: 0 }

获取选定的文本

const getSelectedText = () => window.getSelection().toString();

返回上一个页面

history.back();

// Or
history.go(-1);

隐藏元素

// Pick the method that is suitable for your use case
const hide = (ele) => (ele.style.display = "none");

// Or
const hide = (ele) => (ele.style.visibility = "hidden");

// Or
const hide = (ele) => (ele.hidden = true);

在另一个元素之后插入一个元素

const insertAfter = (ele, anotherEle) =>
  anotherEle.parentNode.insertBefore(ele, anotherEle.nextSibling);

// Or
const insertAfter = (ele, anotherEle) =>
  anotherEle.insertAdjacentElement("afterend", ele);

在其他元素之前插入一个元素

const insertBefore = (ele, anotherEle) =>
  anotherEle.parentNode.insertBefore(ele, anotherEle);

// Or
const insertBefore = (ele, anotherEle) =>
  anotherEle.insertAdjacentElement("beforebegin", ele);

在元素后插入给定的HTML

const insertHtmlAfter = (html, ele) => ele.insertAdjacentHTML("afterend", html);

在元素之前插入给定的HTML

const insertHtmlBefore = (html, ele) =>
  ele.insertAdjacentHTML("beforebegin", html);

重定向到另一个页面

const goTo = (url) => (location.href = url);

重新加载当前页面

const reload = () => location.reload();

// Or
const reload = () => (location.href = location.href);

替换元素

const replace = (ele, newEle) => ele.parentNode.replaceChild(newEle, ele);

滚动到页面顶部

const goToTop = () => window.scrollTo(0, 0);

序列化表单数据

const serialize = (formEle) =>
  Array.from(new FormData(formEle)).reduce(
    (p, [k, v]) =>
      Object.assign({}, p, {
        [k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v,
      }),
    {}
  );

显示一个元素

const show = (ele) => (ele.style.display = "");

从给定文本中剥离HTML

const stripHtml = (html) =>
  new DOMParser().parseFromString(html, "text/html").body.textContent || "";

切换元素

const toggle = (ele) =>
  (ele.style.display = ele.style.display === "none" ? "block" : "none");

// Or
const toggle = (ele) => (ele.hidden = !ele.hidden);

Date Time/日期时间

将AM PM后缀添加到一个小时

// `h` is an hour number between 0 and 23
const suffixAmPm = (h) =>
  `${h % 12 === 0 ? 12 : h % 12}${h < 12 ? "am" : "pm"}`;

// Examples
suffixAmPm(0); // '12am'
suffixAmPm(5); // '5am'
suffixAmPm(12); // '12pm'
suffixAmPm(15); // '3pm'
suffixAmPm(23); // '11pm'

计算两个日期之间的差异天数

const diffDays = (date, otherDate) =>
  Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24));

// Example
diffDays(new Date("2014-12-19"), new Date("2020-01-01")); // 1839

计算两个日期之间的月数

const monthDiff = (startDate, endDate) =>
  Math.max(
    0,
    (endDate.getFullYear() - startDate.getFullYear()) * 12 -
      startDate.getMonth() +
      endDate.getMonth()
  );

// Example
monthDiff(new Date("2020-01-01"), new Date("2021-01-01")); // 12

比较两个日期

// `a` and `b` are `Date` instances
const compare = (a, b) => a.getTime() > b.getTime();

// Example
compare(new Date("2020-03-30"), new Date("2020-01-01")); // true

将日期转换为YYYY-MM-DD格式

// `date` is a `Date` object
const formatYmd = (date) => date.toISOString().slice(0, 10);

// Example
formatYmd(new Date()); // 2020-05-06

将秒转换为hh:mm:ss格式

// `s` is number of seconds
const formatSeconds = (s) => new Date(s * 1000).toISOString().substr(11, 8);

// Or
const formatSeconds = (s) =>
  new Date(s * 1000).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];

// Or
const formatSeconds = (s) =>
  [parseInt(s / 60 / 60), parseInt((s / 60) % 60), parseInt(s % 60)]
    .join(":")
    .replace(/\b(\d)\b/g, "0$1");

// Examples
formatSeconds(200); // 00:03:20
formatSeconds(500); // 00:08:20

从日期中提取年,月,日,小时,分钟,秒和毫秒

// `date` is a `Date` object
const extract = (date) =>
  date
    .toISOString()
    .split(/[^0-9]/)
    .slice(0, -1);

// `extract` is an array of [year, month, day, hour, minute, second, millisecond]

格式化给定语言环境的日期

// `date` is a `Date` object
// `locale` is a locale (en-US, pt-BR, for example)
const format = (date, locale) => new Intl.DateTimeFormat(locale).format(date);

// Example
format(new Date(), "pt-BR"); // 06/05/2020

获取当前日期的四分之一

const getQuarter = (d = new Date()) => Math.ceil((d.getMonth() + 1) / 3);

以秒为单位获取当前时间戳

const ts = () => Math.floor(new Date().getTime() / 1000);

从日期获取一年中的某天

// `date` is a Date object
const dayOfYear = (date) =>
  Math.floor(
    (date - new Date(date.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24)
  );

// Example
dayOfYear(new Date(2020, 04, 16)); // 137

获取日期月份中的第一个日期

const getFirstDate = (d = new Date()) =>
  new Date(d.getFullYear(), d.getMonth(), 1);

获取某月的最后一个日期

const getLastDate = (d = new Date()) =>
  new Date(d.getFullYear(), d.getMonth() + 1, 0);

获取日期的月份名称

// `date` is a Date object
const getMonthName = (date) =>
  [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    " November",
    "December",
  ][date.getMonth()];

获取给定月份的天数

// `month` is zero-based index
const daysInMonth = (month, year) => new Date(year, month, 0).getDate();

获取时区字符串

const getTimezone = () => Intl.DateTimeFormat().resolvedOptions().timeZone;

// Example
getTimezone(); // 'Asia/Saigon'

获取明天的日期

const tomorrow = ((d) => new Date(d.setDate(d.getDate() + 1)))(new Date());

// Or
const tomorrow = new Date(new Date().valueOf() + 1000 * 60 * 60 * 24);

获取一年中的总天数

const numberOfDays = (year) =>
  (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 ? 366 : 365;

// Or
const numberOfDays = (year) =>
  new Date(year, 1, 29).getDate() === 29 ? 366 : 365;

获取日期的工作日

// `date` is a Date object
const getWeekday = (date) =>
  [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
  ][date.getDay()];

获取昨天的日期

const yesterday = ((d) => new Date(d.setDate(d.getDate() - 1)))(new Date());

// Or
const yesterday = new Date(new Date().valueOf() - 1000 * 60 * 60 * 24);

初始化当前日期,但将时间设置为午夜

const midnightOfToday = () => new Date(new Date().setHours(0, 0, 0, 0));

排序日期数组

// `arr` is an array of `Date` items
const sortDescending = (arr) => arr.sort((a, b) => a.getTime() > b.getTime());
const sortAscending = (arr) => arr.sort((a, b) => a.getTime() < b.getTime());

Function/函数

Box handler

const boxHandler = x => ({ next: f => boxHandler(f(x)), done: f => f(x) });

// Example 1
const getPercentNumber = str => boxHandler(str).next(str => str.replace(/\%/, '')).next(str => parseFloat(str)).done(res => res * 0.01);

getPercentNumber('50%');    // 0.5

// Example 2
const getMoney = (price) => Number.parseFloat(price.replace(/\$/, ''));
const getPercent = (percent) => Number.parseFloat(percent.replace(/\%/)) * 0.01;

const getDiscountPrice = (price, discount) => boxHandler(getMoney(price)).done(cents => boxHandler(getPercent(discount)).next(save => cents - (cents * save))).done(res => res);

getDiscountPrice('$6.00', '20%');    // 4.8

检查值是否为函数

const isFunction = (v) =>
  [
    "[object Function]",
    "[object GeneratorFunction]",
    "[object AsyncFunction]",
    "[object Promise]",
  ].includes(Object.prototype.toString.call(v));

// Examples
isFunction(function () {}); // true
isFunction(function* () {}); // true
isFunction(async function () {}); // true

检查值是否是生成器函数

const isGeneratorFunction = (v) =>
  Object.prototype.toString.call(v) === "[object GeneratorFunction]";

// Examples
isGeneratorFunction(function () {}); // false
isGeneratorFunction(function* () {}); // true

检查值是否是异步函数

const isAsyncFunction = (v) =>
  Object.prototype.toString.call(v) === "[object AsyncFunction]";

// Examples
isAsyncFunction(function () {}); // false
isAsyncFunction(function* () {}); // false
isAsyncFunction(async function () {}); // true

从左到右编写功能

// Compose functions from left to right
const pipe =
  (...fns) =>
  (x) =>
    fns.reduce((y, f) => f(y), x);

// Example
const lowercase = (str) => str.toLowerCase();
const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
const reverse = (str) => str.split("").reverse().join("");

const fn = pipe(lowercase, capitalize, reverse);

// We will execute `lowercase`, `capitalize` and `reverse` in order
fn("Hello World") === "dlrow olleH";

组合功能

// Compose functions from right to left
const compose =
  (...fns) =>
  (x) =>
    fns.reduceRight((y, f) => f(y), x);

// Example
const lowercase = (str) => str.toLowerCase();
const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
const reverse = (str) => str.split("").reverse().join("");

const fn = compose(reverse, capitalize, lowercase);

// We will execute `lowercase`, `capitalize` and `reverse` in order
fn("Hello World") === "dlrow olleH";

创建一个接受单个参数的函数

const unary = (fn) => (arg) => fn(arg);

// Example
["1", "2", "3", "4", "5"].map(unary(parseInt)); // [1, 2, 3, 4, 5]

Curry 的函数

const curry = (fn, ...args) =>
  fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args);

// Example
const sum = (a, b, c) => a + b + c;
curry(sum)(1)(2)(3); // 6
curry(sum)(1, 2, 3); // 6
curry(sum, 1)(2, 3); // 6
curry(sum, 1)(2)(3); // 6
curry(sum, 1, 2)(3); // 6
curry(sum, 1, 2, 3); // 6

创建一个空函数

const noop = () => {};

// Or
const noop = Function();
// calling Function() might be detected as using eval by some security tools

延迟函数的计算

// returns a new version of `fn` that returns values as lazy evaluable
const thunkfy =
  (fn) =>
  (...args) =>
  () =>
    fn(...args);

// Example
const heavyComputation = (x) => doStuff(x);
const unnecessarySlow = manyThings
  .map(heavyComputation)
  .find((result) => result.criteria);
const probablyFaster = manyThings
  .map(thunkfy(heavyComputation))
  .find((thunk) => thunk().criteria);

一次执行一个函数

const once = (fn) =>
  (
    (ran = false) =>
    () =>
      ran ? fn : ((ran = !ran), (fn = fn()))
  )();

// Example
let n = 0;
const incOnce = once(() => ++n);
incOnce(); // n = 1
incOnce(); // n = 1
incOnce(); // n = 1

翻转函数的参数

// Reverse the order of arguments
const flip =
  (fn) =>
  (...args) =>
    fn(...args.reverse());

// For binary functions
const flip = (fn) => (b, a) => fn(a, b);

// Or for curried functions
const flip = (fn) => (b) => (a) => fn(a)(b);

// Example
const isParent = (parent, child) => parent.children.includes(child);
const isChild = flip(isParent);

一致函数

const identity = (x) => x;

逻辑异或运算符

// returns `true` if one of the arguments is truthy and the other is falsy

const xor = (a, b) => (a && !b) || (!a && b);

// Or
const xor = (a, b) => !(!a && !b) && !(a && b);

// Or
const xor = (a, b) => Boolean(!a ^ !b);

// Examples
xor(true, true); // false
xor(false, false); // false
xor(true, false); // true
xor(false, true); // true

Memoize的一个函数

const memoize = (fn) =>
  (
    (cache = {}) =>
    (arg) =>
      cache[arg] || (cache[arg] = fn(arg))
  )();

// Example
// Calculate Fibonacci numbers
const fibo = memoize((n) => (n <= 2 ? 1 : fibo(n - 1) + fibo(n - 2)));

fibo(1); // 1
fibo(2); // 1
fibo(3); // 2
fibo(4); // 3
fibo(5); // 5
fibo(6); // 8

部分应用函数

const partial =
  (fn, ...a) =>
  (...b) =>
    fn(...a, ...b);

// Example
const sum = (x, y) => x + y;
const inc = partial(sum, 1);
inc(9); // 10

Uncurry函数

// `fn` is a curried function
// `n` is the depth of parameters
const uncurry =
  (fn, n = 1) =>
  (...args) =>
    (
      (acc) => (args) =>
        args.reduce((x, y) => x(y), acc)
    )(fn)(args.slice(0, n));

// Example
const sum = (a) => (b) => (c) => a + b + c;
uncurry(sum, 1)(1)(2)(3); // 6
uncurry(sum, 2)(1, 2)(3); // 6
uncurry(sum, 3)(1, 2, 3); // 6

Math/数学计算

计算由两个点定义的直线的角度

// In radians
const radiansAngle = (p1, p2) => Math.atan2(p2.y - p1.y, p2.x - p1.x);

// In degrees
const degreesAngle = (p1, p2) =>
  (Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180) / Math.PI;

计算两点之间的距离

const distance = (p1, p2) =>
  Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));

计算两点之间的中点

const midpoint = (p1, p2) => [(p1.x + p2.x) / 2, (p1.y + p2.y) / 2];

检查点是否在矩形内

const isInside = (point, rect) =>
  point.x > rect.left &&
  point.x < rect.right &&
  point.y > rect.top &&
  point.y < rect.bottom;

检查矩形是否包含其他矩形

// Returns true if `a` contains `b`
// (x1, y1) and (x2, y2) are top-left and bottom-right corners
const contains = (a, b) =>
  a.x1 <= b.x1 && a.y1 <= b.y1 && a.x2 >= b.x2 && a.y2 >= b.y2;

检查矩形是否与另一个矩形重叠

// Returns true if `a` overlaps `b`
// (x1, y1) and (x2, y2) are top-left and bottom-right corners
const overlaps = (a, b) =>
  (a.x1 < b.x2 && b.x1 < a.x2) || (a.y1 < b.y2 && b.y1 < a.y2);

将角度转换为弧度

const degsToRads = (deg) => (deg * Math.PI) / 180.0;

将弧度转换为角度

const radsToDegs = (rad) => (rad * 180) / Math.PI;

将数字四舍五入到一个给定值的最接近的倍数

const roundNearest = (value, nearest) => Math.round(value / nearest) * nearest;

// Examples
roundNearest(100, 30); // 90
roundNearest(200, 30); // 210
roundNearest(200, 40); // 200

Misc/杂项

检查代码是否在NodeJS中运行

const isNode =
  typeof process !== "undefined" &&
  process.versions != null &&
  process.versions.node != null;

检查代码是否在浏览器中运行

const isBrowser = typeof window === "object" && typeof document === "object";

清除所有Cookie

const clearCookies = document.cookie
  .split(";")
  .forEach(
    (c) =>
      (document.cookie = c
        .replace(/^ +/, "")
        .replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/`))
  );

将3位数字的颜色转换为6位数字的颜色

const toFullHexColor = (color) =>
  `#${(color.startsWith("#") ? color.slice(1) : color)
    .split("")
    .map((c) => `${c}${c}`)
    .join("")}`;

// Example
toFullHexColor("123"); // '#112233'
toFullHexColor("#123"); // '#112233'
toFullHexColor("#abc"); // '#aabbcc'

转换摄氏到华氏度

const celsiusToFahrenheit = (celsius) => (celsius * 9) / 5 + 32;

// Examples
celsiusToFahrenheit(15); // 59
celsiusToFahrenheit(0); // 32
celsiusToFahrenheit(-20); // -4

将cookie转换为对象

const cookies = document.cookie
  .split(";")
  .map((item) => item.split("="))
  .reduce((acc, [k, v]) => (acc[k.trim().replace('"', "")] = v) && acc, {});

转换华氏到摄氏

const fahrenheitToCelsius = (fahrenheit) => ((fahrenheit - 32) * 5) / 9;

// Examples
fahrenheitToCelsius(59); // 15
fahrenheitToCelsius(32); // 0

将十六进制转换为RGB

const hexToRgb = (hex) =>
  hex
    .replace(
      /^#?([a-f\d])([a-f\d])([a-f\d])$/i,
      (_, r, g, b) => `#${r}${r}${g}${g}${b}${b}`
    )
    .substring(1)
    .match(/.{2}/g)
    .map((x) => parseInt(x, 16));

// Examples
hexToRgb("#00ffff"); // [0, 255, 255]
hexToRgb("#0ff"); // [0, 255, 255]

将RGB颜色转换为十六进制

const rgbToHex = (red, green, blue) =>
  `#${((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1)}`;

// Or
const rgbToHex = (red, green, blue) =>
  `#${[red, green, blue].map((v) => v.toString(16).padStart(2, "0")).join("")}`;

// Example
rgbToHex(0, 255, 255); // '#00ffff'

将URL参数转换为对象

const getUrlParams = (query) =>
  Array.from(new URLSearchParams(query)).reduce(
    (p, [k, v]) =>
      Object.assign({}, p, {
        [k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v,
      }),
    {}
  );

// Examples
getUrlParams(location.search); // Get the parameters of the current URL

getUrlParams("foo=Foo&bar=Bar"); // { foo: "Foo", bar: "Bar" }

// Duplicate key
getUrlParams("foo=Foo&foo=Fuzz&bar=Bar"); // { foo: ["Foo", "Fuzz"], bar: "Bar" }

解码JWT令牌

const decode = (token) =>
  decodeURIComponent(
    atob(token.split(".")[1].replace("-", "+").replace("_", "/"))
      .split("")
      .map((c) => `%${("00" + c.charCodeAt(0).toString(16)).slice(-2)}`)
      .join("")
  );

// Example
decode(`
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
    eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0I
    joxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
`);

// { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }

检测暗模式

const isDarkMode =
  window.matchMedia &&
  window.matchMedia("(prefers-color-scheme: dark)").matches;

Easing functions

// Some easing functions
// See https://gist.github.com/gre/1650294 and https://easings.net

const linear = (t) => t;

const easeInQuad = (t) => t * t;
const easeOutQuad = (t) => t * (2 - t);
const easeInOutQuad = (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t);

const easeInCubic = (t) => t * t * t;
const easeOutCubic = (t) => --t * t * t + 1;
const easeInOutCubic = (t) =>
  t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

const easeInQuart = (t) => t * t * t * t;
const easeOutQuart = (t) => 1 - --t * t * t * t;
const easeInOutQuart = (t) =>
  t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;

const easeInQuint = (t) => t * t * t * t * t;
const easeOutQuint = (t) => 1 + --t * t * t * t * t;
const easeInOutQuint = (t) =>
  t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;

const easeInSine = (t) => 1 + Math.sin((Math.PI / 2) * t - Math.PI / 2);
const easeOutSine = (t) => Math.sin((Math.PI / 2) * t);
const easeInOutSine = (t) => (1 + Math.sin(Math.PI * t - Math.PI / 2)) / 2;

const easeInElastic = (t) => (0.04 - 0.04 / t) * Math.sin(25 * t) + 1;
const easeOutElastic = (t) => ((0.04 * t) / --t) * Math.sin(25 * t);
const easeInOutElastic = (t) =>
  (t -= 0.5) < 0
    ? (0.02 + 0.01 / t) * Math.sin(50 * t)
    : (0.02 - 0.01 / t) * Math.sin(50 * t) + 1;

模拟掷骰子

const throwdice = () => ~~(Math.random() * 6) + 1;

// Examples
throwdice(); // 4
throwdice(); // 1
throwdice(); // 6

编码网址

// `encodeURIComponent` doesn't encode -_.!~*'()
const encode = (url) =>
  encodeURIComponent(url)
    .replace(/!/g, "%21")
    .replace(/~/g, "%7E")
    .replace(/\*/g, "%2A")
    .replace(/'/g, "%27")
    .replace(/\(/g, "%28")
    .replace(/\)/g, "%29")
    .replace(/%20/g, "+");

生成唯一的增量ID

const uid = (() => ((id = 0), () => id++))();

// Examples
uid(); // 0
uid(); // 1
uid(); // 2
uid(); // 3

获取第一个已定义且非null的参数

const coalesce = (...args) =>
  args.find((item) => item !== undefined && item !== null);

// Or
const coalesce = (...args) =>
  args.find((item) => ![undefined, null].includes(item));

// Examples
coalesce(undefined, null, "helloworld", NaN); // 'helloworld'

获取Cookie的值

const cookie = (name) =>
  `; ${document.cookie}`.split(`; ${name}=`).pop().split(";").shift();

// Example
cookie("_ga"); // GA1.2.825309271.1581874719

从URL获取参数的值

const getParam = (url, param) =>
  new URLSearchParams(new URL(url).search).get(param);

// Example
getParam("http://udtool.com?message=hello", "message"); // 'hello'

获取字符串中变量的类型

const getTypeOf = (obj) =>
  Object.prototype.toString.call(obj).match(/\[object (.*)\]/)[1];

// Examples
getTypeOf("hello world"); // String
getTypeOf(1000); // Number
getTypeOf(Infinity); // Number
getTypeOf(true); // Boolean
getTypeOf(Symbol()); // Symbol
getTypeOf(null); // Null
getTypeOf(undefined); // Undefined
getTypeOf({}); // Object
getTypeOf([]); // Array
getTypeOf(/[a-z]/g); // RegExp
getTypeOf(new Date(2021)); // Date
getTypeOf(new Error()); // Error
getTypeOf(function () {}); // Function
getTypeOf((a, b) => a + b); // Function
getTypeOf(async () => {}); // AsyncFunction
getTypeOf(document); // HTMLDocument

如果页面位于HTTP中,则将其重定向到HTTPS

const redirectHttps = () =>
  location.protocol === "https:"
    ? {}
    : location.replace(`https://${location.href.split("//")[1]}`);

// Or
const redirectHttps = () =>
  location.protocol === "https:" ? {} : (location.protocol = "https:");

按顺序运行Promises

// `promises` is an array of `Promise`
const run = (promises) =>
  promises.reduce(
    (p, c) => p.then((rp) => c.then((rc) => [...rp, rc])),
    Promise.resolve([])
  );

// Example
run(promises).then((results) => {
  // `results` is an array of promise results in the same order
});

交换两个变量

[a, b] = [b, a];

// Or
a = [b, (b = a)][0];

// Or
a = ((x) => x)(b, (b = a));

// Or
// (only works with numbers)
a = b + ((b = a), 0);

a = b * ((b = a), 1);

等待一段时间

const wait = async (milliseconds) =>
  new Promise((resolve) => setTimeout(resolve, milliseconds));

Number/数字

在数字后添加序数后缀

// `n` is a position number
const addOrdinal = (n) =>
  `${n}${["st", "nd", "rd"][((((n + 90) % 100) - 10) % 10) - 1] || "th"}`;

// Or
const addOrdinal = (n) => `${n}${[, "st", "nd", "rd"][/1?.$/.exec(n)] || "th"}`;

// Or
const addOrdinal = (n) =>
  `${n}${[, "st", "nd", "rd"][(n % 100 >> 3) ^ 1 && n % 10] || "th"}`;

// Or
const addOrdinal = (n) =>
  `${n}${
    { one: "st", two: "nd", few: "rd", other: "th" }[
      new Intl.PluralRules("en", { type: "ordinal" }).select(n)
    ]
  }`;

// Examples
addOrdinal(1); // '1st'
addOrdinal(2); // '2nd'
addOrdinal(3); // '3rd'
addOrdinal(11); // '11th'
addOrdinal(12); // '13th'
addOrdinal(13); // '13th'

计算斐波那契数

const fibo = (n, memo = {}) =>
  memo[n] || (n <= 2 ? 1 : (memo[n] = fibo(n - 1, memo) + fibo(n - 2, memo)));

// Examples
fibo(1); // 1
fibo(2); // 1
fibo(3); // 2
fibo(4); // 3
fibo(5); // 5
fibo(6); // 8

计算参数的平均值

const average = (...args) => args.reduce((a, b) => a + b) / args.length;

// Example
average(1, 2, 3, 4); // 2.5

计算参数除法

const division = (...args) => args.reduce((a, b) => a / b);

// Example
division(1, 2, 3, 4); // 0.04166666666666666

计算数字的阶乘

const factorial = (n) => (n <= 1 ? 1 : n * factorial(n - 1));

// Examples
factorial(2); // 2
factorial(3); // 6
factorial(4); // 24
factorial(5); // 120
factorial(6); // 720

计算集合索引的mod

const mod = (a, b) => ((a % b) + b) % b;

// Examples
mod(-1, 5); // 4
mod(3, 5); // 3
mod(6, 5); // 1

计算参数除法的余数

const remainder = (...args) => args.reduce((a, b) => a % b);

// Example
remainder(1, 2, 3, 4); // 1

计算参数之和

const sum = (...args) => args.reduce((a, b) => a + b);

// Example
sum(1, 2, 3, 4); // 10

将一个数字夹在两个值之间

const clamp = (val, min = 0, max = 1) => Math.max(min, Math.min(max, val));

// Example
clamp(199, 10, 25); // 25

计算两个数字之间的最大公约数

const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));

// Example
gcd(10, 15); // 5

将数字转换为等效字符

const toChars = (n) =>
  `${n >= 26 ? toChars(Math.floor(n / 26) - 1) : ""}${
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n % 26]
  }`;

// Examples
toChars(0); // A
toChars(1); // B
toChars(25); // Z

toChars(26); // AA
toChars(27); // AB
toChars(51); // AZ

toChars(701); // ZZ
toChars(702); // AAA
toChars(703); // AAB

将字符串转换为数字

const toNumber = (str) => +str;

// Example
toNumber("42"); // 42

将十进制递归转换为二进制

const decToBi = (num) =>
  num === 0 ? 0 : (num % 2) + 10 * decToBi(~~(num / 2));

// Example
decToBi(10); //1010

从数字中获取数字数组

const digitize = (n) => `${n}`.split("").map((v) => parseInt(v, 10));

// Or
const digitize = (n) => [...`${n}`].map((v) => parseInt(v, 10));

// Example
digitize(123); // [1, 2, 3]

相乘参数

const mul = (...args) => args.reduce((a, b) => a * b);

// Example
mul(1, 2, 3, 4); // 24

前缀为零的整数

const prefixWithZeros = (number, length) =>
  (number / Math.pow(10, length)).toFixed(length).substr(2);

// Or
const prefixWithZeros = (number, length) =>
  `${Array(length).join("0")}${number}`.slice(-length);

// Or
const prefixWithZeros = (number, length) =>
  String(number).padStart(length, "0");

// Example
prefixWithZeros(42, 5); // '00042'

将数字四舍五入到给定的数字

const round = (n, decimals = 0) =>
  Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);

// Examples
round(1.234567, 3); // 1.235
round(1.234567, 4); // 1.2346

减去参数

const subtract = (...args) => args.reduce((a, b) => a - b);

// Example
subtract(1, 2, 3, 4); // -8

将数字截断为十进制

const truncate = (n) => ~~n;

// Examples
truncate(25.198726354); // 25
truncate(-25.198726354); // -25

将数字截断到给定的小数位数而不四舍五入

const toFixed = (n, fixed) =>
  `${n}`.match(new RegExp(`^-?\\d+(?:\.\\d{0,${fixed}})?`))[0];

// Or
const toFixed = (n, fixed) => ~~(Math.pow(10, fixed) * n) / Math.pow(10, fixed);

// Examples
toFixed(25.198726354, 1); // 25.1
toFixed(25.198726354, 2); // 25.19
toFixed(25.198726354, 3); // 25.198
toFixed(25.198726354, 4); // 25.1987
toFixed(25.198726354, 5); // 25.19872
toFixed(25.198726354, 6); // 25.198726

Object/对象

检查多个对象是否相等

const isEqual = (...objects) =>
  objects.every((obj) => JSON.stringify(obj) === JSON.stringify(objects[0]));

// Examples
isEqual({ foo: "bar" }, { foo: "bar" }); // true
isEqual({ foo: "bar" }, { bar: "foo" }); // false

创建一个没有属性的空映射

// `map` doesn't have any properties
const map = Object.create(null);

// The following `map` has `__proto__` property
// const map = {};

根据键和值对创建一个对象

const toObj = (arr) => Object.fromEntries(arr);

// Or
const toObj = (arr) => arr.reduce((a, c) => ((a[c[0]] = c[1]), a), {});

// Example
toObj([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]); // { a: 1, b: 2, c: 3 }

从对象数组中提取属性值

const pluck = (objs, property) => objs.map((obj) => obj[property]);

// Example
pluck(
  [
    { name: "John", age: 20 },
    { name: "Smith", age: 25 },
    { name: "Peter", age: 30 },
  ],
  "name"
); // ['John', 'Smith', 'Peter']

获取对象给定路径的值

const getValue = (path, obj) =>
  path.split(".").reduce((acc, c) => acc && acc[c], obj);

// Example
getValue("a.b", { a: { b: "Hello World" } }); // 'Hello World';

不可更改地重命名对象键

const renameKeys = (keysMap, obj) =>
  Object.keys(obj).reduce(
    (acc, key) => ({ ...acc, ...{ [keysMap[key] || key]: obj[key] } }),
    {}
  );

// Examples
const obj = { a: 1, b: 2, c: 3 };
const keysMap = { a: "d", b: "e", c: "f" };
renameKeys(keysMap, obj); // { d: 1, e: 2, f: 3 }

反转对象的键和值

const invert = (obj) =>
  Object.keys(obj).reduce((res, k) => Object.assign(res, { [obj[k]]: k }), {});

// Or
const invert = (obj) =>
  Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));

// Example
invert({ a: "1", b: "2", c: "3" }); // { 1: 'a', 2: 'b', 3: 'c' }

忽略对象的属性子集

const omit = (obj, keys) =>
  Object.keys(obj)
    .filter((k) => !keys.includes(k))
    .reduce((res, k) => Object.assign(res, { [k]: obj[k] }), {});

// Example
omit({ a: "1", b: "2", c: "3" }, ["a", "b"]); // { c: '3' }

选择一个对象的属性子集

const pick = (obj, keys) =>
  Object.keys(obj)
    .filter((k) => keys.includes(k))
    .reduce((res, k) => Object.assign(res, { [k]: obj[k] }), {});

// Example
pick({ a: "1", b: "2", c: "3" }, ["a", "b"]); // { a: '1', b: '2' }

从对象中删除所有null和未定义的属性

const removeNullUndefined = (obj) =>
  Object.entries(obj).reduce(
    (a, [k, v]) => (v == null ? a : ((a[k] = v), a)),
    {}
  );

// Or
const removeNullUndefined = (obj) =>
  Object.entries(obj)
    .filter(([_, v]) => v != null)
    .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});

// Or
const removeNullUndefined = (obj) =>
  Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));

// Example
removeNullUndefined({
  foo: null,
  bar: undefined,
  fuzz: 42,
}); // { fuzz: 42 }

浅复制一个对象

const shallowCopy = obj => Object.assign({}, obj);

// or
const shallowCopy = obj => {...obj};

按对象的属性对对象进行排序

const sort = (obj) =>
  Object.keys(obj)
    .sort()
    .reduce((p, c) => ((p[c] = obj[c]), p), {});

// Example
const colors = {
  white: "#ffffff",
  black: "#000000",
  red: "#ff0000",
  green: "#008000",
  blue: "#0000ff",
};
sort(colors);
/*
{
    black: '#000000',
    blue: '#0000ff',
    green: '#008000',
    red: '#ff0000',
    white: '#ffffff',
}
*/

Random/随机

产生一个随机的布尔值

const randomBoolean = () => Math.random() >= 0.5;

生成给定范围内的随机浮点数

const randomFloat = (min, max) => Math.random() * (max - min) + min;

生成随机的十六进制颜色

const randomColor = () =>
  `#${Math.random().toString(16).slice(2, 8).padEnd(6, "0")}`;

// Or
const randomColor = () => `#${(~~(Math.random() * (1 << 24))).toString(16)}`;

生成给定范围内的随机整数

const randomInteger = (min, max) =>
  Math.floor(Math.random() * (max - min + 1)) + min;

生成一个随机IP地址

const randomIp = () =>
  Array(4)
    .fill(0)
    .map((_, i) => Math.floor(Math.random() * 255) + (i === 0 ? 1 : 0))
    .join(".");

// Example
randomIp(); // 175.89.174.131

产生随机信号

const randomSign = () => (Math.random() >= 0.5 ? 1 : -1);

从给定字符生成随机字符串

const generateString = (length, chars) =>
  Array(length)
    .fill("")
    .map((v) => chars[Math.floor(Math.random() * chars.length)])
    .join("");

// Example
generateString(
  10,
  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
);

使用Node crypto模块生成随机字符串

const randomStr = () => require("crypto").randomBytes(32).toString("hex");

生成给定长度的随机字符串

const generateString = (length) =>
  Array(length)
    .fill("")
    .map((v) => Math.random().toString(36).charAt(2))
    .join("");

产生随机的UUID

const uuid = (a) =>
  a
    ? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
    : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);

生成给定范围内的随机整数数组

const randomArrayInRange = (min, max, n) =>
  Array.from(
    { length: n },
    () => Math.floor(Math.random() * (max - min + 1)) + min
  );

// Example
randomArrayInRange(1, 100, 10); // [11, 82, 41, 35, 76, 83, 43, 15, 60, 54]

获取随机项目并将其从数组中删除

const randomItem = (arr) => arr.splice((Math.random() * arr.length) | 0, 1);

// Example
const arr = [1, 3, 5, 7, 9];
randomItem(arr); // 7
// arr = [1, 3, 5, 9]

从数组中获取随机项

const randomItem = (arr) => arr[(Math.random() * arr.length) | 0];

获取数组的随机项

const randomItems = (arr, count) =>
  arr
    .concat()
    .reduce(
      (p, _, __, arr) =>
        p[0] < count
          ? [
              p[0] + 1,
              p[1].concat(arr.splice((Math.random() * arr.length) | 0, 1)),
            ]
          : p,
      [0, []]
    )[1];

// Examples
randomItems([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3); // [4, 8, 5]
randomItems(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"], 4); // ['e', 'c', 'h', 'j']

选择一个对象的随机属性

const randomProp = (obj) =>
  Object.keys(obj)[(Math.random() * Object.keys(obj).length) | 0];

// Example
const colors = {
  aqua: "#00ffff",
  azure: "#f0ffff",
  beige: "#f5f5dc",
  black: "#000000",
  blue: "#0000ff",
  brown: "#a52a2a",
  cyan: "#00ffff",
  darkblue: "#00008b",
  darkcyan: "#008b8b",
  darkgrey: "#a9a9a9",
  darkgreen: "#006400",
  darkkhaki: "#bdb76b",
  darkmagenta: "#8b008b",
  darkolivegreen: "#556b2f",
  darkorange: "#ff8c00",
  darkorchid: "#9932cc",
  darkred: "#8b0000",
  darksalmon: "#e9967a",
  darkviolet: "#9400d3",
  fuchsia: "#ff00ff",
  gold: "#ffd700",
  green: "#008000",
  indigo: "#4b0082",
  khaki: "#f0e68c",
  lightblue: "#add8e6",
  lightcyan: "#e0ffff",
  lightgreen: "#90ee90",
  lightgrey: "#d3d3d3",
  lightpink: "#ffb6c1",
  lightyellow: "#ffffe0",
  lime: "#00ff00",
  magenta: "#ff00ff",
  maroon: "#800000",
  navy: "#000080",
  olive: "#808000",
  orange: "#ffa500",
  pink: "#ffc0cb",
  purple: "#800080",
  violet: "#800080",
  red: "#ff0000",
  silver: "#c0c0c0",
  white: "#ffffff",
  yellow: "#ffff00",
};
randomProp(colors); // 'red'

String/字符串

首字符串大写

const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;

// Or
const capitalize = ([first, ...rest]) =>
  `${first.toUpperCase()}${rest.join("")}`;

// Example
capitalize("hello world"); // 'Hello world'

检查路径是否相对

const isRelative = (path) => !/^([a-z]+:)?[\\/]/i.test(path);

// Examples
isRelative("/foo/bar/baz"); // false
isRelative("C:\\foo\\bar\\baz"); // false
isRelative("foo/bar/baz.txt"); // true
isRelative("foo.md"); // true

检查字符串是否包含重复的字符序列

const consistsRepeatedSubstring = (str) =>
  `${str}${str}`.indexOf(str, 1) !== str.length;

// Example
consistsRepeatedSubstring("aa"); // true
consistsRepeatedSubstring("aaa"); // true
consistsRepeatedSubstring("ababab"); // true
consistsRepeatedSubstring("abc"); // false

检查字符串是否是回文

const isPalindrome = (str) => str === str.split("").reverse().join("");

// Examples
isPalindrome("abc"); // false
isPalindrom("abcba"); // true

检查URL是否是绝对的

const isAbsoluteUrl = (url) => /^[a-z][a-z0-9+.-]*:/.test(url);

// Example
isAbsoluteUrl("https://1loc.dev"); // true
isAbsoluteUrl("https://1loc.dev/foo/bar"); // true
isAbsoluteUrl("1loc.dev"); // false
isAbsoluteUrl("//1loc.dev"); // false

检查两个字符串是否拼字

const areAnagram = (str1, str2) =>
  str1.toLowerCase().split("").sort().join("") ===
  str2.toLowerCase().split("").sort().join("");

// Examples
areAnagram("listen", "silent"); // true
areAnagram("they see", "the eyes"); // true
areAnagram("node", "deno"); // true

将一个字母转换为关联的表情符号

const letterToEmoji = (c) =>
  String.fromCodePoint(c.toLowerCase().charCodeAt() + 127365);

// Examples
letterToEmoji("a"); // 🇦
letterToEmoji("b"); // 🇧

将字符串转换为camelCase

const toCamelCase = (str) =>
  str.trim().replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ""));

// Examples
toCamelCase("background-color"); // backgroundColor
toCamelCase("-webkit-scrollbar-thumb"); // WebkitScrollbarThumb
toCamelCase("_hello_world"); // HelloWorld
toCamelCase("hello_world"); // helloWorld

将字符串转换为PascalCase

const toPascalCase = (str) =>
  (str.match(/[a-zA-Z0-9]+/g) || [])
    .map((w) => `${w.charAt(0).toUpperCase()}${w.slice(1)}`)
    .join("");

// Examples
toPascalCase("hello world"); // 'HelloWorld'
toPascalCase("hello.world"); // 'HelloWorld'
toPascalCase("foo_bar-baz"); // FooBarBaz

将字符串转换为URL段

const slugify = (string) =>
  string
    .toLowerCase()
    .replace(/\s+/g, "-")
    .replace(/[^\w-]+/g, "");

// Example
slugify("Chapter One: Once upon a time..."); // 'chapter-one-once-upon-a-time'

将Windows文件路径转换为Unix路径

const toUnixPath = (path) =>
  path.replace(/[\\/]+/g, "/").replace(/^([a-zA-Z]+:|\.\/)/, "");

// Examples
toUnixPath("./foo/bar/baz"); // foo/bar/baz
toUnixPath("C:\\foo\\bar\\baz"); // /foo/bar/baz

将camelCase转换为kebab-case,反之亦然

const kebabToCamel = (str) => str.replace(/-./g, (m) => m.toUpperCase()[1]);

const camelToKebab = (str) =>
  str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();

// Examples
kebabToCamel("background-color"); // 'backgroundColor'
camelToKebab("backgroundColor"); // 'background-color'

将snake_case转换为camelCase

const snakeToCamel = (str) =>
  str.toLowerCase().replace(/(_\w)/g, (m) => m.toUpperCase().substr(1));

// Example
snakeToCamel("HELLO_world"); // 'helloWorld'

将Excel列的名称转换为数字

const getIndex = (col) =>
  col.split("").reduce((prev, next) => prev * 26 + parseInt(next, 36) - 9, 0);

// Examples
getIndex("A"); // 1
getIndex("B"); // 2
getIndex("C"); // 3
getIndex("Z"); // 26

getIndex("AA"); // 27
getIndex("AB"); // 28
getIndex("AC"); // 29
getIndex("AZ"); // 52

getIndex("AAA"); // 703
getIndex("AAB"); // 704

计算字符串中字符的出现

const countOccurrences = (str, char) =>
  [...str].reduce((a, v) => (v === char ? a + 1 : a), 0);

// Or
const countOccurrences = (str, char) =>
  str.split("").reduce((a, v) => (v === char ? a + 1 : a), 0);

// Or
const countOccurrences = (str, char) =>
  [...str].filter((item) => item === char).length;

// Or
const countOccurrences = (str, char) =>
  str.split("").filter((item) => item === char).length;

// Examples
countOccurrences("a.b.c.d.e", "."); // 4

字符串去大写

const decapitalize = (str) => `${str.charAt(0).toLowerCase()}${str.slice(1)}`;

// Or
const decapitalize = ([first, ...rest]) =>
  `${first.toLowerCase()}${rest.join("")}`;

// Example
decapitalize("Hello world"); // 'hello world'

转义HTML特殊字符

const escape = (str) =>
  str
    .replace(/&/g, "&")
    .replace(//g, ">")
    .replace(/'/g, "'")
    .replace(/"/g, """);

// Or
const escape = (str) =>
  str.replace(
    /[&<>"']/g,
    (m) =>
      ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[
        m
      ])
  );

生成字符串的哈希

const hash = (str) =>
  str
    .split("")
    .reduce((prev, curr) => (Math.imul(31, prev) + curr.charCodeAt(0)) | 0, 0);

// Or
const hash = (str) =>
  str
    .split("")
    .reduce((prev, curr) => ((prev << 5) - prev + curr.charCodeAt(0)) | 0, 0);

// Example
hash("hello"); // 99162322

获取不带任何参数的基本URL

const baseUrl = (url) =>
  url.indexOf("?") === -1 ? url : url.slice(0, url.indexOf("?"));

// Or
// Note that `includes` isn't supported in IE 11
const baseUrl = (url) =>
  url.includes("?") ? url.slice(0, url.indexOf("?")) : url;

// Example
baseUrl("https://udtool.com/path/sub/path?foo=bar&hello=world"); // 'https://udtool.com/path/sub/path'

从文件名获取文件扩展名

const ext = (fileName) => fileName.split(".").pop();

从URL获取文件名

const fileName = (url) => url.substring(url.lastIndexOf("/") + 1);

// Example
fileName("http://udtool.com/path/to/document.pdf"); // 'document.pdf'

获取字符串的长度(以字节为单位)

const bytes = (str) => new Blob([str]).size;

// Examples
bytes("hello world"); // 11
bytes("🎉"); // 4

获取字符串中的字符数

const characterCount = (str, char) => str.split(char).length - 1;

// Or
const characterCount = (str, char) =>
  str.replace(new RegExp(String.raw`[^${char}]`, "g"), "").length;

// Examples
characterCount("192.168.1.1", "."); // 3
characterCount("star wars", "s"); // 2

使字符串的第一个字符小写

const lowercaseFirst = (str) => `${str.charAt(0).toLowerCase()}${str.slice(1)}`;

// Example
lowercaseFirst("Hello World"); // 'hello World'

标准化文件路径斜杠

const normalizePath = (path) => path.replace(/[\\/]+/g, "/");

// Example
normalizePath("\\foo\\bar\\baz\\"); // /foo/bar/baz/
normalizePath(".//foo//bar///////baz/"); // ./foo/bar/baz/

从字符串中删除空格

const removeSpaces = (str) => str.replace(/\s/g, "");

// Example
removeSpaces("hel lo wor ld"); // 'helloworld'

重复一个字符串

const repeat = (str, numberOfTimes) => str.repeat(numberOfTimes);

// Or
const repeat = (str, numberOfTimes) => Array(numberOfTimes + 1).join(str);

将所有换行符替换为br元素

const nl2br = (str) => str.replace(new RegExp("\r?\n", "g"), "
"); // In React str.split("\n").map((item, index) => ( {item}
));

用一个空格替换多个空格

// Replace spaces, tabs and new line characters
const replaceSpaces = (str) => str.replace(/\s\s+/g, " ");

// Only replace spaces
const replaceOnlySpaces = (str) => str.replace(/  +/g, " ");

// Example
replaceSpaces("this\n   is     \ta    \rmessage"); // 'this is a message'

将字符串的第一个给定字符数替换为另一个字符

const mask = (str, num, mask) =>
  `${str}`.slice(num).padStart(`${str}`.length, mask);

// Example
mask(1234567890, 3, "*"); // ***4567890

反转字符串

const reverse = (str) => str.split("").reverse().join("");

// Or
const reverse = (str) => [...str].reverse().join("");

// Or
const reverse = (str) =>
  str.split("").reduce((rev, char) => `${char}${rev}`, "");

// Or
const reverse = (str) =>
  str === "" ? "" : `${reverse(str.substr(1))}${str.charAt(0)}`;

// Example
reverse("hello world"); // 'dlrow olleh'

按字母顺序对字符串的字符进行排序

const sort = (str) =>
  str
    .split("")
    .sort((a, b) => a.localeCompare(b))
    .join("");

// Example
sort("hello world"); // dehllloorw

从字符串中删除ANSI代码

const stripAnsiCodes = (str) =>
  str.replace(
    /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
    ""
  );

// Example
stripAnsiCodes("\u001B[4mcake\u001B[0m"); // 'cake'
stripAnsiCodes(
  "\u001B[0m\u001B[4m\u001B[42m\u001B[31mfoo\u001B[39m\u001B[49m\u001B[24mfoo\u001B[0m"
); // 'foofoo'

交换字符串中的字符大小写

const swapCase = (str) =>
  str
    .split("")
    .map((c) => (c === c.toLowerCase() ? c.toUpperCase() : c.toLowerCase()))
    .join("");

// Example
swapCase("Hello World"); // 'hELLO wORLD'

在字符串的开始和结束处修剪斜杠

const trimSlashes = (str) => str.replace(/^\/+|\/+$/g, "");

// Or
const trimSlashes = (str) => str.split("/").filter(Boolean).join("/");

// Example
trimSlashes("//hello/world///"); // hello/world

削减一些字符

const trim = (str, char) => str.split(char).filter(Boolean).join();

// Examples
trim("/hello world//", "/"); // hello world
trim('"hello world"', '"'); // hello world
trim("   hello world ", " "); // hello world

从文件名中删除文件扩展名

const trimExt = (fileName) =>
  fileName.indexOf(".") === -1
    ? fileName
    : fileName.split(".").slice(0, -1).join(".");

// Examples
trimExt("document"); // document
trimExt("document.pdf"); // document
trimExt("document.2020.pdf"); // document.2020

在完整单词处截断字符串

const truncate = (str, max, suffix) =>
  str.length < max
    ? str
    : `${str.substr(
        0,
        str.substr(0, max - suffix.length).lastIndexOf(" ")
      )}${suffix}`;

// Example
truncate("This is a long message", 20, "..."); // 'This is a long...'

取消转义HTML特殊字符

const unescape = (str) =>
  str
    .replace(/&/g, "&")
    .replace(//g, ">")
    .replace(/�*39;/g, "'")
    .replace(/"/g, '"');

将字符串中每个单词的第一个字符大写

const uppercaseWords = (str) =>
  str
    .split(" ")
    .map((w) => `${w.charAt(0).toUpperCase()}${w.slice(1)}`)
    .join(" ");

// Or
const uppercaseWords = (str) =>
  str.replace(/^(.)|\s+(.)/g, (c) => c.toUpperCase());

// Example
uppercaseWords("hello world"); // 'Hello World'

Validator/检查校验

检查日期是否是工作日

// `date` is a Date object
const isWeekday = (date = new Date()) => date.getDay() % 6 !== 0;

检查日期是否是周末

// `date` is a Date object
const isWeekend = (date = new Date()) => date.getDay() % 6 === 0;

检查日期是否在两个日期之间

// `min`, `max` and `date` are `Date` instances
const isBetween = (date, min, max) =>
  date.getTime() >= min.getTime() && date.getTime() <= max.getTime();

检查日期是否是今天

// `date` is a Date object
const isToday = (date) =>
  date.toISOString().slice(0, 10) === new Date().toISOString().slice(0, 10);

检查日期是否在当年

// `date` is a Date object
const isCurrentYear = (date) =>
  date.getUTCFullYear() === new Date().getUTCFullYear();

检查平面数组是否有重复值

const hasDuplicateValues = (arr) => new Set(arr).size !== arr.length;

// Examples
hasDuplicateValues(["h", "e", "l", "l", "o"]); // true
hasDuplicateValues(["w", "o", "r", "d"]); // false

检查给定的整数是否是质数

const isPrime = (num) =>
  num > 1 &&
  Array(Math.floor(Math.sqrt(num)) - 1)
    .fill(0)
    .map((_, i) => i + 2)
    .every((i) => num % i !== 0);

检查数字是否为2的幂

const isPowerOfTwo = (number) => (number & (number - 1)) === 0;

// Examples
isPowerOfTwo(256); // true
isPowerOfTwo(129); // false

检查数字是否为偶数

const isEven = (number) => number % 2 === 0;

// Or
const isEven = (number) => (number & 1) === 0;

// Or
const isEven = (number) => !(number & 1);

// Or
const isEven = (number) => Number.isInteger(number / 2);

// Examples
isEven(1); // false
isEven(2); // true

检查数字是否在给定范围内

const inRange = (num, a, b, threshold = 0) =>
  Math.min(a, b) - threshold <= num && num <= Math.max(a, b) + threshold;

// Example
inRange(10, 5, 15); // true
inRange(10, 5, 6); // false
inRange(10, 15, 5); // true
inRange(-10, -5, -15); // true

检查数字是否为负

const isNegative = (number) => Math.sign(number) === -1;

// Or
const isNegative = (number) => number < 0;

// Examples
isNegative(-3); // true
isNegative(8); // false

检查数字是否为奇数

const isOdd = (number) => number % 2 !== 0;

// Or
const isOdd = (number) => !!(number & 1);

// Or
const isOdd = (number) => !Number.isInteger(number / 2);

// Examples
isOdd(1); // true
isOdd(2); // false

检查数字是否为正

const isPositive = (number) => Math.sign(number) === 1;

// Examples
isPositive(3); // true
isPositive(-8); // false

检查字符串是否包含小写字符

const containsLowerCase = (str) => str !== str.toUpperCase();

// Examples
containsLowerCase("Hello World"); // true
containsLowerCase("HELLO WORLD"); // false

检查字符串是否仅包含ASCII字符

const isAscii = (str) => /^[\x00-\x7F]+$/.test(str);

检查字符串是否仅包含数字

const isNumeric = (str) => !/[^0-9]/.test(str);

// Examples
isNumeric(2); // true
isNumeric("23"); // true
isNumeric("00123"); // true

isNumeric("1.23"); // false
isNumeric("-Infinity"); // false
isNumeric("Infinity"); // false
isNumeric("NaN"); // false

检查字符串是否仅包含字母和数字

const isAlphanumeric = (str) => /^[0-9A-Z]+$/i.test(str);

// Examples
isAlphanumeric("helloworld"); // true
isAlphanumeric("HelloWorld"); // true
isAlphanumeric("hello world"); // false
isAlphanumeric("hello123"); // true
isAlphanumeric("hello 123"); // false

检查字符串是否仅包含字母

const isAlpha = (str) => /^[A-Z]+$/i.test(str);

// Examples
isAlpha("helloworld"); // true
isAlpha("HelloWorld"); // true
isAlpha("hello world"); // false
isAlpha("0123456789"); // false

检查字符串是否包含大写字符

const containsUpperCase = (str) => str !== str.toLowerCase();

// Examples
containsUpperCase("Hello World"); // true
containsUpperCase("hello world"); // false

检查字符串是否包含空格

const containsWhitespace = (str) => (str) => /\s/.test(str);

// Example
containsWhitespace("hello world"); // true

检查字符串是否为十六进制颜色

const isHexColor = (color) =>
  /^#([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$/i.test(color);

// Examples
isHexColor("#012"); // true
isHexColor("#A1B2C3"); // true
isHexColor("012"); // false
isHexColor("#GHIJKL"); // false

检查字符串是否为十六进制数字

const isHexadecimal = (str) => /^[A-F0-9]+$/i.test(str);

// Or
const isHexadecimal = (str) =>
  str.split("").every((c) => "0123456789ABCDEFabcdef".indexOf(c) !== -1);

// Examples
isHexadecimal("123"); // true
isHexadecimal("A1B2C3"); // true
isHexadecimal("#123"); // false

检查字符串是否为MongoDB ObjectId

const isMongoId = (str) => str.length === 24 && /^[A-F0-9]+$/i.test(str);

// Or
const isMongoId = (str) =>
  str.length === 24 &&
  str.split("").every((c) => "0123456789ABCDEFabcdef".indexOf(c) !== -1);

检查字符串是否为八进制数字

const isOctal = (str) => /^(0o)?[0-7]+$/i.test(str);

检查字符串是否为小写

const isLowerCase = (str) => str === str.toLowerCase();

检查字符串是否为大写

const isUpperCase = (str) => str === str.toUpperCase();

检查值是否是业务标识符代码

const isBIC = (value) =>
  /^[a-zA-Z]{6}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?$/.test(value);

检查值是否为数字

const isNumber = (value) => !isNaN(parseFloat(value)) && isFinite(value);

检查值是否为普通对象

const isPlainObject = (v) =>
  !!v &&
  typeof v === "object" &&
  (v.__proto__ === null || v.__proto__ === Object.prototype);

// Examples
isPlainObject(null); // false
isPlainObject("hello world"); // false
isPlainObject([]); // false
isPlainObject(Object.create(null)); // false
isPlainObject(function () {}); // false

isPlainObject({}); // true
isPlainObject({ a: "1", b: "2" }); // true

检查值是否为正则表达式

const isRegExp = (value) =>
  Object.prototype.toString.call(value) === "[object RegExp]";

检查值是否为字符串

const isString = (value) =>
  Object.prototype.toString.call(value) === "[object String]";

// Examples
isString("hello world"); // true
isString(new String("hello world")); // true
isString(10); // false

检查值是否是对象

const isObject = (v) => v !== null && typeof v === "object";

// Examples
isObject(null); // false
isObject("hello world"); // false

isObject({}); // true
isObject([]); // true

检查值是否为base32编码

const isBase32 = (value) =>
  value.length % 8 === 0 && /^[A-Z2-7]+=*$/.test(value);

检查值是否为base58编码

// It doesn't accept the I, O, l characters
const isBase58 = (value) => /^[A-HJ-NP-Za-km-z1-9]*$/.test(value);

检查值是否为base64编码

const isBase64 = (value) =>
  /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/.test(
    value
  );

检查值是否为零

const isNil = (value) => value == null;

检查一年是否为leap年

const isLeapYear = (year) =>
  (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;

// Or
// Get the number of days in February
const isLeapYear = (year) => new Date(year, 1, 29).getDate() === 29;

检查所有数组元素是否等于给定值

const isEqual = (arr, value) => arr.every((item) => item === value);

// Or
// Ends earlier for false arrays
const isEqual = (arr, value) => !arr.some((item) => item !== value);

// Examples
isEqual(["foo", "foo"], "foo"); // true
isEqual(["foo", "bar"], "foo"); // false
isEqual(["bar", "bar"], "foo"); // false

检查数组中的所有项是否相等

const areEqual = (arr) =>
  arr.length > 0 && arr.every((item) => item === arr[0]);

// Or
const areEqual = (arr) => new Set(arr).size === 1;

// Examples
areEqual([1, 2, 3, 4]); // false
areEqual(["hello", "hello", "hello"]); // true

检查数组是否包含与某些条件匹配的值

const contains = (arr, criteria) => arr.some((v) => criteria(v));

// Or
const contains = (arr, criteria) => arr.some(criteria);

// Or
const contains = (arr, criteria) => arr.filter(criteria).length > 0;

// Examples
contains([10, 20, 30], (v) => v > 25); // true
contains([10, 20, 30], (v) => v > 100 || v < 15); // true
contains([10, 20, 30], (v) => v > 100); // false

检查数组是否为空

const isNotEmpty = (arr) => Array.isArray(arr) && Object.keys(arr).length > 0;

// Examples
isNotEmpty([]); // false
isNotEmpty([1, 2, 3]); // true

检查一个数组是否是其他数组的子集

// Check if `b` is subset of `a`
const isSubset = (a, b) => new Set(b).size === new Set(b.concat(a)).size;

// Or
const isSubset = (a, b) => b.join("|").includes(a.join("|"));

// Examples
isSubset([1, 2], [1, 2, 3, 4]); // true
isSubset([1, 2, 5], [1, 2, 3, 4]); // false
isSubset([6], [1, 2, 3, 4]); // false

检查对象是否为Promise

const isPromise = (obj) =>
  !!obj &&
  (typeof obj === "object" || typeof obj === "function") &&
  typeof obj.then === "function";

检查对象是否为数组

const isArray = (obj) => Array.isArray(obj);

检查对象是否为空

const isEmpty = (obj) =>
  Reflect.ownKeys(obj).length === 0 && obj.constructor === Object;

// Or for enumerable property names only
const isEmpty = (obj) => JSON.stringify(obj) === "{}";

验证公历日期

// `m`: the month (zero-based index)
// `d`: the day
// `y`: the year
const isValidDate = (m, d, y) =>
  0 <= m &&
  m <= 11 &&
  0 < y &&
  y < 32768 &&
  0 < d &&
  d <= new Date(y, m, 0).getDate();

关于JavaScript 一行代码大全介绍:

1、JavaScript 一行代码大全,前端开发者必备的JavaScript代码片段速查手册,收集了大量的JS功能代码。

2、工具说明:

  • 汇集了数百个实用 JavaScript 单行代码片段,覆盖前端开发核心需求。
  • 内容包含数组、字符串、日期、DOM操作、数学计算等多个常用分类。
  • 所有代码片段均经过验证,支持一键复制,可直接应用于实际项目中。
  • 界面简洁清晰,专为提升开发者编写代码的效率和简洁度而设计。

3、工具使用说明:

  • 通过页面顶部的搜索框输入关键词,实时查找特定的功能代码。
  • 点击左侧导航栏的分类菜单,按类别筛选浏览不同的代码片段。
  • 在代码卡片区域找到目标代码,点击“复制”按钮完成一键复制。
  • 将复制的代码粘贴到您的 JavaScript 或 TypeScript 项目文件中即可使用。

4、适合场景:

  • 日常开发中需要快速实现数组去重、时间格式化等常见功能。
  • 代码重构或优化时,寻找更简洁、优雅的实现方式替代冗余逻辑。
  • 前端初学者学习 ES6+ 高阶语法和实用编程技巧的参考资料。
  • 技术面试前快速复习常用 API 的组合用法和代码实现细节。

专业网站定制服务

企业官网
个人博客
实验室官网
作品集网站
求职/升学网站
机构官网
个人学术网站

附带服务:网站安全 | 网站加速 | 技术支持

立即咨询定制方案
资深专精 · 快速交付 · 售后保障

推荐工具
主页 搜索 收藏 开灯关灯