防止转义符转义
const path = `C:\web\index.html`; // 'C:web.html'
const unescapedPath = String.raw`C:\web\index.html`; // 'C:\web\index.html'
获取字符数
存在 Unicode 码点大于0xFFFF
的字符时, 使用 for of 获取字符数
String.prototype.charLength = function () {
let length = 0;
for (let chat of this) {
length += 1;
}
return length;
};
let s = "𠮷🎈";
function charLength(str) {
let length = 0;
for (let char of str) {
length += 1;
}
return length;
}
console.log(
"🚀 ~ file: byteLength.js:15 ~ charLength ~ charLength:",
charLength(s),
s.charLength()
);
去除首尾空格 - trim()
function myTrim(str) {
return str.replace(/(^\s+)|(\s+$)/g,'')//将前空格和后空格替换为空
}
获取字符串字节大小
const byteSize = str => new Blob([str]).size;
byteSize('😀'); // 4
byteSize('Hello World'); // 11
字符串格式化、美化
超出数量显示…
// 简单按字符长度截取
if (row.length > 28) {
row = row.slice(0, 13) + '...'
}
// 按byte长度截取
function cutStringByByte(str: string, len: number): string {
if (!str && typeof str != 'undefined') {
return ''
}
let num = 0
let subStr = ''
for (const i of str) {
num += i.charCodeAt(0) > 255 ? 2 : 1
if (num > len) {
subStr += '...'
break
} else {
subStr += i
}
}
return subStr
}
连字符与驼峰互转 camelize & hyphenate
// 将函数变为可缓存结果的函数
const cacheStringFunction = (fn) => {
const cache = Object.create(null);
return (str) => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
};
};
// 连字符转驼峰
const camelizeRE = /-(\w)/g;
const camelize = cacheStringFunction((str) => {
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ""));
});
// 清爽版
// const camelize = str => str.replace(camelizeRE, (_, c) => { return c ? c.toUpperCase() : '';
// });
// 举例:
console.log("🚀 ~ file: test.js ~ line 10 ~ camelize", camelize("on-click-a"));
// 驼峰转连字符
const hyphenateRE = /\B([A-Z])/g;
const hyphenate = cacheStringFunction((str) =>
str.replace(hyphenateRE, "-$1").toLowerCase()
);
// 清爽版const
// hyphenate = str => str.replace(hyphenateRE, '-$1').toLowerCase();
// 仿照 camelize 写法
// const hyphenate = (str) =>
// str.replace(hyphenateRE, (_, c) => {
// return c ? `-${c.toLowerCase()}` : "";
// });
// 举例:onClickA => on-click-ahyphenate('onClickA');
console.log("🚀 ~ file: test.js ~ line 10 ~ camelize", hyphenate("onClickA"));
base64 编解码
基于atob和btoa的base64编码和解码
function utf8_to_b64( str ) {
return window.btoa(unescape(encodeURIComponent( str )));
}
function b64_to_utf8( str ) {
return decodeURIComponent(escape(window.atob( str )));
}
utf8_to_b64('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
不依赖浏览器环境
/**
* base64编码和解码
* @param str
* @returns
*/
const base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function (e: string) {
let t = "";
let n: number,
r: number,
i: number,
s: number,
o: number,
u: number,
a: number;
let f = 0;
e = base64._utf8_encode(e);
while (f < e.length) {
n = e.charCodeAt(f++);
r = e.charCodeAt(f++);
i = e.charCodeAt(f++);
s = n >> 2;
o = ((n & 3) << 4) | (r >> 4);
u = ((r & 15) << 2) | (i >> 6);
a = i & 63;
if (isNaN(r)) {
u = a = 64;
} else if (isNaN(i)) {
a = 64;
}
t =
t +
this._keyStr.charAt(s) +
this._keyStr.charAt(o) +
this._keyStr.charAt(u) +
this._keyStr.charAt(a);
}
return t;
},
decode: function (e: string) {
let t = "";
let n: number, r: number, i: number;
let s: number, o: number, u: number, a: number;
let f = 0;
e = e.replace(/[^A-Za-z0-9+/=]/g, "");
while (f < e.length) {
s = this._keyStr.indexOf(e.charAt(f++));
o = this._keyStr.indexOf(e.charAt(f++));
u = this._keyStr.indexOf(e.charAt(f++));
a = this._keyStr.indexOf(e.charAt(f++));
n = (s << 2) | (o >> 4);
r = ((o & 15) << 4) | (u >> 2);
i = ((u & 3) << 6) | a;
t = t + String.fromCharCode(n);
if (u != 64) {
t = t + String.fromCharCode(r);
}
if (a != 64) {
t = t + String.fromCharCode(i);
}
}
t = base64._utf8_decode(t);
return t;
},
_utf8_encode: function (e: string) {
e = e.replace(/rn/g, "n");
let t = "";
for (let n = 0; n < e.length; n++) {
let r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r);
} else if (r > 127 && r < 2048) {
t += String.fromCharCode((r >> 6) | 192);
t += String.fromCharCode((r & 63) | 128);
} else {
t += String.fromCharCode((r >> 12) | 224);
t += String.fromCharCode(((r >> 6) & 63) | 128);
t += String.fromCharCode((r & 63) | 128);
}
}
return t;
},
_utf8_decode: function (e: string) {
let t = "",
n = 0,
r = 0,
c2 = 0,
c3 = 0;
while (n < e.length) {
r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r);
n++;
} else if (r > 191 && r < 224) {
c2 = e.charCodeAt(n + 1);
t += String.fromCharCode(((r & 31) << 6) | (c2 & 63));
n += 2;
} else {
c2 = e.charCodeAt(n + 1);
c3 = e.charCodeAt(n + 2);
t += String.fromCharCode(
((r & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
);
n += 3;
}
}
return t;
},
};
export default base64;
颜色转换
JavaScript颜色转换的核心就是进制间的转换。RGB格式其实就是十进制表示法,所以,十六进制颜色与RGB颜色的转换就是十六进制与十进制之间的转换。
十六进制转换为十进制相对容易些,核心代码如下示例:parseInt("0xFF")
,其结果就是255,”0x”就表明当前是16进制,由于parseInt后面无参数,默认就是转换为10进制了。
十进制转换为16进制,核心代码如下:var r=255; r.toString(16);
,其结果是FF。”16″表示数值转换为16进制字符串。
const hexToRGB = hex => {
let alpha = false,
h = hex.slice(hex.startsWith('#') ? 1 : 0);
if (h.length === 3) h = [...h].map(x => x + x).join('');
else if (h.length === 8) alpha = true;
h = parseInt(h, 16);
return (
'rgb' +
(alpha ? 'a' : '') +
'(' +
(h >>> (alpha ? 24 : 16)) +
', ' +
((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) +
', ' +
((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) +
(alpha ? `, ${h & 0x000000ff}` : '') +
')'
);
};
hexToRGB('#27ae60ff'); // 'rgba(39, 174, 96, 255)'
hexToRGB('27ae60'); // 'rgb(39, 174, 96)'
hexToRGB('#fff'); // 'rgb(255, 255, 255)'
const RGBToHex = (r, g, b) =>
((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
RGBToHex(255, 165, 1); // 'ffa501'
const RGBToHSB = (r, g, b) => {
r /= 255;
g /= 255;
b /= 255;
const v = Math.max(r, g, b),
n = v - Math.min(r, g, b);
const h =
n === 0 ? 0 : n && v === r ? (g - b) / n : v === g ? 2 + (b - r) / n : 4 + (r - g) / n;
return [60 * (h < 0 ? h + 6 : h), v && (n / v) * 100, v * 100];
};
RGBToHSB(252, 111, 48);
// [18.529411764705856, 80.95238095238095, 98.82352941176471]
const RGBToHSL = (r, g, b) => {
r /= 255;
g /= 255;
b /= 255;
const l = Math.max(r, g, b);
const s = l - Math.min(r, g, b);
const h = s
? l === r
? (g - b) / s
: l === g
? 2 + (b - r) / s
: 4 + (r - g) / s
: 0;
return [
60 * h < 0 ? 60 * h + 360 : 60 * h,
100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
(100 * (2 * l - s)) / 2,
];
};
RGBToHSL(45, 23, 11); // [21.17647, 60.71428, 10.98039]
const HSBToRGB = (h, s, b) => {
s /= 100;
b /= 100;
const k = (n) => (n + h / 60) % 6;
const f = (n) => b * (1 - s * Math.max(0, Math.min(k(n), 4 - k(n), 1)));
return [255 * f(5), 255 * f(3), 255 * f(1)];
};
HSBToRGB(18, 81, 99); // [252.45, 109.31084999999996, 47.965499999999984]
const HSLToRGB = (h, s, l) => {
s /= 100;
l /= 100;
const k = n => (n + h / 30) % 12;
const a = s * Math.min(l, 1 - l);
const f = n =>
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
return [255 * f(0), 255 * f(8), 255 * f(4)];
};
HSLToRGB(13, 100, 11); // [56.1, 12.155, 0]
uuid生成随机 字符串
/**
* 生成随机id
* @param {*} length
* @param {*} chars
*/
export function uuid(length, chars) {
chars =
chars ||
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
length = length || 8
var result = ''
for (var i = length; i > 0; --i)
result += chars[Math.floor(Math.random() * chars.length)]
return result
}
基于URL或者Crypto.getRandomValues生成UUID
function genUUID() {
const url = URL.createObjectURL(new Blob([]));
// const uuid = url.split("/").pop();
const uuid = url.substring(url.lastIndexOf('/')+ 1);
URL.revokeObjectURL(url);
return uuid;
}
genUUID() // cd205467-0120-47b0-9444-894736d873c7
function uuidv4() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
}
uuidv4() // 38aa1602-ba78-4368-9235-d8703cdb6037
//chrome 92支持
crypto.randomUUID()
基于toLocaleString千分位
function formatMoney(num){
return (+num).toLocaleString("en-US");
}
console.log(formatMoney(123456789)); // 123,456,789
console.log(formatMoney(6781)) // 6,781
console.log(formatMoney(5)) // 5
//超大的数
formatMoney(19999999933333333333333) // 19,999,999,933,333,333,000,000
内容脱敏
在一些涉及到用户隐私情况下,可能会遇到对用户的手机号身份证号之类的信息脱敏,但是这个脱敏数据的规则是根据用户信息要脱敏字段动态的生成的,此时我们动态拼接正则来实现一个动态脱敏规则
const encryptReg = (before = 3, after = 4) => {
return new RegExp('(\\d{' + before + '})\\d*(\\d{' + after + '})');
};
// 使用:'13456789876'.replace(encryptReg(), '$1****$2') -> "134****9876"
// 手机号中间四位变成*
export const telFormat = (tel) => {
tel = String(tel);
return tel.substr(0,3) + "****" + tel.substr(7);
};
搜索
// select下拉组件的搜索
function filterTableOption(input: string, option: any) {
return (
JSON.parse(option.value)
.table_name.toLowerCase()
.indexOf(input.toLowerCase()) >= 0 ||
JSON.parse(option.value)
.schema_name.toLowerCase()
.indexOf(input.toLowerCase()) >= 0
)
}
// sourceString.toLowerCase().indexOf(targetString.toLowerCase()) >= 0