记录一些常见的函数实现2

2022/8/16

# 工具函数系列

# From Vue

# From React

# From Angular

# From DOM

  1. 检测某个元素是否聚焦
const hasFocus = (el) => el === document.activeElement;
1
  1. 获取某个元素所有的兄弟元素
const a = (el) => [].slice.call(el.parentNode.children).filter((child) => child !== el);
1
  1. 获取当前选择的文本
const getSelectedText = () => window.getSelection().toString();
1
  1. 获取所有 cookie 并转为对象
const getCookies = () =>
  document.cookie
    .split(";")
    .map((item) => item.split("="))
    .reduce((acc, [k, v]) => (acc[k.trim().replace('"', "")] = v) && acc, {});
1
2
3
4
5
  1. 清除所有 cookie
const clearCookies = () => document.cookie
  .split(';')
  .forEach(c => document.cookie = c.splace(/^+/, '')
          .replace(/=.*/,`=;expires=${new Date().toUTCString()};path=/`))
  );
1
2
3
4
5
  1. 将 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,
      }),
    {}
  );
1
2
3
4
5
6
7
8
  1. 检测是否为暗模式
const isDarkMode = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
1

# From Array

  1. 比较两个数组
const isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
1
  1. 将数组转为对象
const arrayToObject = (arr, key) => arr.reduce((a, b) => ({ ...a, [b[key]]: b }), {});
1
  1. 获取数组最后一个元素
// ES13
const lastItem = (arr) => arr.at(-1);
1
2

# From Object

  1. 检测多个对象是否相等
const isEqual = (...objects) => objects.every((obj) => JSON.stringify(obj) === JSON.stringify(objects[0]));
1
  1. 从对象数组中提取属性值
const pluck = (objs, property) => objs.map((obj) => obj[property]);
1
  1. 反转对象的 key/value
const invert = (obj) => Object.keys(obj).reduce((res, k) => Object.assign(res, { [obj[k]]: k }), {});
1
  1. 从对象中删除值为 null 和 undefined 的属性
const removeNullAndUndefined = (obj) =>
  Object.entries(obj).reduce((a, [k, v]) => (v == null ? a : ((a[k] = v), a)), {});
1
2
  1. 按照对象的属性对对象排序
const sort = (obj) =>
  Object.keys(obj)
    .sort()
    .reduce((p, c) => ((p[c] = obj[c]), p), {});
1
2
3
4
  1. 检测对象是否为数组
const isArray = (obj) => Array.isArray(obj);
1
  1. 检测对象是否为 Promise
const isPromise = (obj) =>
  !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
1
2

# From String

  1. 检查路径是否是相对路径
const isRelative = (path) => !/^([az]+:)?[\\/]/i.test(path);
1
  1. 生成 IP 地址
const randomIp = () =>
  Array(4)
    .fill(0)
    .map((_, i) => Math.floor(Math.random() * 255) + (i === 0 ? 1 : 0))
    .join(".");
1
2
3
4
5
  1. 生成十六进制颜色字符串
const randomColor = () => `#${Math.random().toString(16).slice(2, 8).padEnd(6, "0")}`;
1
  1. 生成 rgb 颜色字符串
const randomRgbColor = () =>
  `rgb(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)})`;
1
2
  1. 下划线转驼峰
const toHump = (str) => str.replace(/\_(\w)/g, (all, letter) => letter.toUpperCase());
1
  1. 驼峰转下划线横线
const toLine = (str) => str.replace(/([A-Z])/g, "_$1").toLowerCase();
1
  1. 检查字符串是否是十六进制颜色
const isHexColor = (color) => /^#([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$/i.test(color);
1
  1. RGB 字符串转十六进制字符串
const rgbToHex = (r, g, b) => "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
1

# From Date

  1. 两个日期之间相差的天数
const diffDays = (date, otherDate) => Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24));
1
  1. 检查日期是否有效
const isDateValid = (...val) => !Number.isNaN(new Date(...val).valueOf());
1
  1. 检测代码是否处于 Node.js 环境
const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
1
  1. 检测代码是否处于浏览器环境
const isBrowser = typeof window === "object" && typeof document === "object";
1

# 正则匹配金额

// 匹配人民币
let [reg, info, rmb, result] = [
  /^(¥)(-?[0-9,]+)(\.[0-9]+)?/,
  ["金额", "符号", "整数部分", "小数分部"],
  ["¥10.01", "¥10", "¥1,111.01", "¥1,000,12", "¥0.1", "¥10.00"],
];
rmb.forEach((value) => {
  console.log("---------------------------------------------------------------------------------");
  for (let i = 0, result = reg.exec(value); i < result.length; i++) {
    console.log(`${info[i]} = ${result[i]}`);
  }
});
1
2
3
4
5
6
7
8
9
10
11
12

# js 替代 eval 方法

项目中遇到需要支持用户输入 js 并加以解析的场景。eval() 本身不太好,所以查找了下其他实现:

function new_eval(str) {
  var fn = Function;
  return new fn("return " + str)();
}
1
2
3
4

# 解析 16 进制序列为 UTF-8 字符

function decodeHexToUtf8(str: string, isJsonStr = false): string | object {
  // 正则表达式,用于匹配形如 [0xe5] 的UTF-8编码序列
  const hexPattern = /\[0x([0-9a-f]{2})\]/gi;

  // 转换匹配到的16进制序列为UTF-8字符
  const decodedString = str.replace(hexPattern, (match, p1) => {
    // 将16进制值转换为字节
    return String.fromCharCode(parseInt(p1, 16));
  });

  // 使用TextDecoder将字节序列转换为字符串
  const bytes = [];
  for (let i = 0; i < decodedString.length; i++) {
    const charCode = decodedString.charCodeAt(i);
    if (charCode <= 0xff) {
      bytes.push(charCode);
    }
  }
  const _str = new TextDecoder("utf-8").decode(new Uint8Array(bytes));

  if (isJsonStr) {
    // 尝试解析JSON字符串
    try {
      return JSON.parse(_str);
    } catch (e) {
      console.error("Error parsing JSON:", e);
      return null;
    }
  }
  return _str;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
上次更新: 1/9/2024