https://www.imqianduan.com/javascript/236.html
https://juejin.cn/post/6898962197335490573
策略模式 https://www.cnblogs.com/hollischuang/p/13186766.html
https://blog.csdn.net/qq_34703156/article/details/122863975
https://blog.csdn.net/java_atguigu/article/details/123919921
https://baijiahao.baidu.com/s?id=1713405091858312136&wfr=spider&for=pc
https://www.cnblogs.com/shine-lovely/p/12836773.html
https://www.cnblogs.com/fundebug/p/13_js_utilities_you_need.html
https://gitee.com/zhangyangbin/js-utils
https://github.com/proYang/outils
https://juejin.cn/post/7048963605462515743
异步并发限制 https://zhuanlan.zhihu.com/p/123968952
utils
number
string
date
cache
is判断类型,设备类型
语雀空间
https://xk70b1.yuque.com/dashboard
https://www.yuque.com/yuque/blog/hrwynrqgoexdynw4
collect
https://github.com/ecrmnn/collect.js
https://collect.js.org/installation.html
yarn add collect.js
mathjs
https://github.com/josdejong/mathjs
https://mathjs.org/
sugarjs
sugarjs https://sugarjs.com/
lazy.js
https://github.com/dtao/lazy.js
http://danieltao.com/lazy.js/
函数调用
// 冗余
function test1() { console.log('test1'); };
function test2() { console.log('test2'); };
var test3 = 1;
if (test3 == 1) { test1(); }
else { test2(); }
// 简单
(test3 === 1? test1:test2)();
多行字符串
// 冗余
const data = 'abc abc abc abc abc abc\n\t'
+ 'test test,test test test test\n\t'
// 简洁
const data = `abc abc abc abc abc abc
test test,test test test test`
隐式返回
// 冗余
function getArea(diameter) {
return Math.PI * diameter
}
// 简洁
getArea = diameter => (
Math.PI * diameter;
)
字符串重复多次
// 冗余
let test = '';
for(let i = 0; i < 5; i ++) {
test += 'test ';
}
// 简洁
'test '.repeat(5);
幂乘
// 冗余
Math.pow(2,3);
// 简洁而
2**3 // 8
获取对象的key, value值
Object.keys()、Object.values()、Object.entries()的用法
图片懒加载
可以通过为图片文件添加loading="lazy"的属性来实现:
![](image.png)
数组去重
1.借助Set
const arr = [12,34,565,12,34,1,3,1]
const newArr = Array.from(new Set(arr))
console.log('newArr',newArr);
const numbers = [1,2,3,4,1,2,3,4];
const result = [... new Set(numbers)];
?.链式合并运算
// 错误写法,当某一层级值为null或undefined时,会报错
const userName = list.info.base.userName;
// 正确写法(我们常用的方式)
const userName = (list && list.info && list.info.base &&
list.info.base.userName) || 'userName'// 错误写法,当某一层级值为null或
undefined时,会报错
const userName = list.info.base.userName;
// 正确写法(我们常用的方式)
const userName = (list && list.info && list.info.base &&
list.info.base.userName) || 'userName'
es2020引入链合并运算符,简化上面的写法
const userName = list?.info?.base?.userName || 'userName';
?.运算符这在有时候处理对象时非常有用,看下面案例,person.name返回undefined然后在调用toString这时肯定会报错,
这时使用?.运算符就不会产生错误,?.运算符是只有在当值不是undefined时才会调用toString方法。
双位运算符
双位运算符比Math.floor(),Math.ceil()速度快
`~~7.5 // 7
Math.ceil(7.5) // 8
Math.floor(7.5) // 7
~~-7.5 // -7
Math.floor(-7.5) // -8
Math.ceil(-7.5) // -7
~~双非运算符
~~双非运算符可以用于向下取整
console.log(~~4.3) // 4
??运算符只有前面的值是undefined or null才会执行,工作中有的情况下使用,我们来看一下。
let status = undefined;
let text = status ?? "暂无"
console.log(text) // 暂无
??的意思是 如果?? 左边的值是null 或者是undefined,那么就返回右边的
const height = 0
console.log(height||100)//100
cosole.log(height ?? 100)//0
检查数值是不是NAN
Number.isNaN(1+NaN); // true; NaN 数值与非数值运算的结果NaN
深度 clone
const objectA = {a: 1, b: 2};
const clonedA = JSON.parse(JSON.stringify(objectA));
字符串转数字
let numberStr = "123";
+numberStr; // 123
numberStr = '123.12';
+numberStr; // 123.12
数字转字符串
直接在需要转换的数字后加上空字符串,最快捷的转换,比调用toString快很多
判断正负值
// Math.sign()
// 判断正负, 还是0; 对非数值,能转化的转化; 不能转的就是NaN
// 返回值: 正 +1; 负 -1; 0; 0; 其他值 NaN
Array.of(传一组数值); 用于将一组值,转换为数组
Array.from(param1, param2)方法用于将两类对象转为真正的数组
参数1: 一个对象 ==> 伪数组对象和可遍历(iterable)的对象
参数2: 回调函数 ==> 类似于数组的map方法,对每个元素进行处理,将处理后的值放入返回的数组。
return值: 一个数组;
示例:
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
// 0: 'a',
// 1: 'b',
// 2: 'c',
// length: 3
};
let real_arr = Array.from(arrayLike);
在两个数组匹配取值的情况,如果嵌套循环,效率低,并且代码看着不美观。利用对象的特性,可以简化复杂度。例如根据id匹配员工工资
双数组匹配
const employees = [
{id: 1, name: 'Tom'},
{id: 2, name: 'Jerry'},
{id: 3, name: 'Jim'},
{id: 4, name: 'Kate'}
];
const salary = [
{id: 1, salary: 10000},
{id: 2, salary: 20000},
{id: 3, salary: 30000},
{id: 4, salary: 40000}
];
const salaryObj = {};
salary.map(({id, salary}) => salaryObj[id] = salary);
employees.map(e => e.salary = salaryObj[e.id]);
JavaScript 中只有六个虚值
undefined
null
NaN
0
"" (空字符串)
false
myArray.filter(Boolean);
去除当前数组里的false值
# !!
!!0; // false
!!undefined; // false
!!null; // false
!!(()=>{}); // true
原始的 myArray 会保持不变
myArray
.map(item => {
// Do your changes and return the new item
})
.filter(Boolean);
合并多个对象
const user = {
name: 'John Ludwig',
gender: 'Male'
};
const college = {
primary: 'Mani Primary School',
secondary: 'Lass Secondary School'
};
const skills = {
programming: 'Extreme',
swimming: 'Average',
sleeping: 'Pro'
};
const summary = {...user, ...college, ...skills};
数组排序
默认情况下 sort 方法把数组元素转换为字符串,并对其进行字典排序。在对数字数组进行排序时,这有可能会导致一些问题
[0,10,4,9,123,54,1].sort((a,b) => a-b);
[0, 1, 4, 9, 10, 54, 123]
阻止用户在你的网页上单击鼠标右键
<body oncontextmenu="return false">
<div></div>
</body>
获取数组中的最后一项
过对 splice 方法的参数传入负整数,来数获取组末尾的元素
let array = [0, 1, 2, 3, 4, 5, 6, 7]
console.log(array.slice(-1));
[7]
console.log(array.slice(-2));
[6, 7]
console.log(array.slice(-3));
[5, 6, 7]
Promise.all 的主要注意事项是,当一个 Promise 拒绝时,该方法将引发错误。这意味着你的代码不会等到你所有的 promise 都完成
等到所有 promise 都完成后,无论它们被拒绝还是被解决,都可以使用 Promise.allSettled。此方法在 ES2020 的最终版本得到支持
即使某些 promise 被拒绝,Promise.allSettled 也会从你所有的 promise 中返回结果
const PromiseArray = [
Promise.resolve(100),
Promise.reject(null),
Promise.resolve("Data release"),
Promise.reject(new Error('Something went wrong'))];
Promise.allSettled(PromiseArray).then(res =>{
console.log(res);
}).catch(err => console.log(err));
//[
//{status: "fulfilled", value: 100},
//{status: "rejected", reason: null},
//{status: "fulfilled", value: "Data release"},
//{status: "rejected", reason: Error: Something went wrong ...}
//]
try..catch..finally
const getData = async () => {
try {
setLoading(true);
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts"
);
const data = await response.json();
setData(data);
} catch (error) {
console.log(error);
setToastMessage(error);
} finally {
setLoading(false); // 不管是否报错,最后都会执行
}
};
getData();
别名结构赋值
const object = { number: 10 };
// Grabbing number
const { number } = object;
// Grabbing number and renaming it as otherNumber
const { number: otherNumber } = object;
console.log(otherNumber); //10
eval 生成正则表达式,动态正则匹配
let str = 'hello world ';
let reg1 = `/hello/g`;
let reg2 = `/world/g`;
eval(reg1).test(str); // true
eval(reg2).test(str); // true
Form表单
String字符串
https://github.com/jprichardson/string.js
文本选中
https://github.com/EvandroLG/selecting
npm install selecting
音频&视频
图片相关
轮播图
https://github.com/sachinchoolur/lightgallery.js
https://github.com/fengyuanchen/cropperjs
https://fengyuanchen.github.io/viewerjs/
图片懒加载
https://github.com/dinbror/blazy/
https://dinbror.dk/blazy/?ref=github
JS数据可视化
- d3.js
- three.js
- echarts.js
BOM操作
domurl
https://github.com/Mikhus/domurl
npm install domurl
urijs
import URI from 'urijs'
禁止页面另存为:标签加入以下代码
<noscript>
<iframe src=”*.htm”></iframe>
</noscript>
禁止复制页面内容
<body
οncοntextmenu=”return false” 禁止鼠标右键菜单
onselectstart=”return false” 禁止鼠标选取
οndragstart=”return false” 禁止鼠标拖拽
>
</body>
html encode & decode
https://github.com/mathiasbynens/he
原生JS的重要性
你不需要 lodash
- You may not need Lodash / Underscore
- https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore
你不需要 Jquery
function loop(array, fn){
for ( var i = 0; i < array.length; i++ )
fn.call( array, array[i], i );
}
// 最小值
function smallest(array){
return Math.min.apply( Math, array );
}
// 最大值
function largest(array){
return Math.max.apply( Math, array );
}
// sleep
const sleep = ms => new Promise(resolve => setTimeout(() => resolve(), ms))
/**
* 函数防抖
* @params callback 回调函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
function debounce(callback, wait, immediate) {
let timeout
return function() {
let _this = this
let args = arguments // arguments 必须在函数内部是用
if(timeout) clearTimeout(timeout)
if(immediate) {
const callNow = !timeout
timeout = setTimeout(() => {
timeout = null
}, wait)
if(callNow) func.apply(_this, args)
}
else {
timeout = setTimeout(() => {
callback.apply(_this, args)
}, wait)
}
}
}
// 函数节流
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
// as much as it can, without ever going more than once per `wait` duration;
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
function throttle(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function() {
var now = Date.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
};
// 数组去重的20中思路
// setTimeout实现 setInterval
function _setInterval(){
let timer = setTimeout(() =>{
_setInterval()
clearTimeout(timer)
}, 1000)
}
function myInterval(callback, time){
function inner() {
callback()
setTimeout(inner, time)
}
inner()
}
// 闭包
(function(){
const utils = window._utils_ = function() {}
})();
const utils = (function(){
function utils() {}
})()
Object.prototype.keys = function(){
var keys = [];
for ( var i in this )
keys.push( i );
return keys;
}
Function.prototype.bind = function(object){
var fn = this;
return function(){
return fn.apply(object, arguments);
};
};
// 生成26个字母
Array.from({length: 26}, (_, i) => String.fromCharCode(65+i))
本地字典
dict.js
// Badge 状态
export const STATUS = {
0: { label: '在线', value: 'green' }, // 绿
1: { label: '故障', value: 'orange'}, // 橙
2: { label: '预警', value: 'yellow' }, // 黄
3: { label: '离线', value: 'default' }, // 灰
}
export const TIMESTAMP = {
'h1': () => datenow() - oneHour,
'h6': () => datenow() - oneHour * 6,
'h12':() => datenow() - oneHour * 12,
'day1':() => datenow() - oneDay,
'day3':() => datenow() - oneDay * 3,
'day7':() => datenow() - oneDay * 7,
}
// JSON转字符串
export function JsonEncode(obj) {
return JSON.stringify(obj);
}
// 字符串转JSON
export function JsonDecode(str) {
let value = '';
try {
value = JSON.parse(str);
}
catch(e) {
// unquote 转义字符也会导致解析失败
const newString = str.replace(/"/g, '\"');
value = JSON.parse(newString);
}
return value;
}
// 转义 url
export function DecodeUri(string) {
const { decodeURIComponent, escape } = window;
return decodeURIComponent(escape(string));
}
// 字符串转JSON
export function EncodeUri(string) {
const { encodeURIComponent, unescape } = window;
return unescape(encodeURIComponent(string));
}
// 获取 URL参数
export function getParams() {
const query = window.location.search.substr(1);
const queryArray = query.split('&');
return queryArray.reduce((prev, next) => {
const [key, value] = next.split('=');
prev[key] = value;
return prev;
}, {});
}
// 获取 URL参数,正则
export function getParams() {
const REG = /(([\w\-]+){1}(\=([^\&\n\r\t]*){1})?)/g;
const query = REG.exec(window.location.search.substr(1));
}
export function getUrl() {
return window.location.href;
}
export function isFile(url) {
return url.includes('file://')
}
export function isHttp() {
return url.includes('http://')
}
export function isHttps() {
return url.includes('https://')
}
export function isLocalhost(url) {
const reg = /^(https?\:\/\/)(localhost|127\.0\.0\.1)(\:[\d]+)?(\/(.)*)?$/;
return reg.test(url);
}
// Number
export function isFloat(value) {
return value % 1 !== 0;
}
// type类型
export function isDate(value) {
return Object.prototype.toString.call(value) === '[object Date]';
}
export function isFunction(value) {
return typeof (value) === 'function';
}
export function isArray(value) {
if (Array.isArray) {
return Array.isArray(value);
}
return (Object.prototype.toString.call(value) === '[object Array]');
}
export function isObject(value) {
return Object.prototype.toString.call(value) === '[object Object]';
}
export function isBoolean() {
return typeof (val) === 'boolean'
}
export function isError(value) {
return value instanceof Error;
}
export function isNumber(value) {
return typeof (value) === 'number' && !isNaN(value) && isFinite(value)
}
export function isNull() {
// undefined, null
return value == null;
}
export function isRegExp(value) {
return value instanceof RegExp;
}
export function isString(value) {
return typeof (value) === 'string';
}
export function isJSON(value) {
if (!isString(value)) return false;
try {
const values = JSON.parse(value);
return values !== null && typeof (values) === 'object';
} catch (e) {
return false;
}
}
export function isBase64() {
if (!isString(value) || value.trim() === '') return false;
try {
return btoa(atob(value)) == value;
} catch (e) {
return false;
}
}
export function isUndefined(value) {
return typeof (value) === 'undefined';
}
export function isNaN(value) {
return isNaN(value);
}
export function isBase64() {
}
export function isDate() { }
export function isDate() { }
export function isDate() { }
export function isDate() { }
export function isEqual(value, value2) {
if (Object.is(value, value2)) return true;
return JSON.stringify(value) === JSON.stringify(value2);
}
// String
export function trimAll(value) {
return value.replace(/^[\s]+|[\s]+$/gm, '');
}
export function trimLeft(value) {
return value.replace(/^[\s]+/gm, '');
}
export function trimRight(value) {
return value.replace(/[\s]+$/gm, '');
}
export function decodeBase64(string) {
let value = '';
const input = string.replace(/[^A-Za-z0-9\+\/\=]/g, '');
try {
value = window.atob(input);
} catch (e) {
const chars = {
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9, 'K': 10, 'L': 11, 'M': 12,
'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25,
'a': 26, 'b': 27, 'c': 28, 'd': 29, 'e': 30, 'f': 31, 'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36, 'l': 37, 'm': 38,
'n': 39, 'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45, 'u': 46, 'v': 47, 'w': 48, 'x': 49, 'y': 50, 'z': 51,
'0': 52, '1': 53, '2': 54, '3': 55, '4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 61, '+': 62, '/': 63, '=': 64
};
let chr1, chr2, chr3;
let enc1, enc2, enc3, enc4;
let i = 0;
let j = input.length;
while (i < j) {
enc1 = chars[input.charAt(i++)];
enc2 = chars[input.charAt(i++)];
enc3 = chars[input.charAt(i++)];
enc4 = chars[input.charAt(i++)];
chr1 = ((enc1 << 2) | (enc2 >> 4));
chr2 = (((enc2 & 15) << 4) | (enc3 >> 2));
chr3 = (((enc3 & 3) << 6) | enc4);
value += String.fromCharCode(chr1);
if (enc3 !== 64) {
value += String.fromCharCode(chr2);
}
if (enc4 !== 64) {
value += String.fromCharCode(chr3);
}
}
}
return decodeURIComponent(value);
}
export function encodeBase64(string) {
// const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
const input = encodeURIComponent(string);
let value = '';
try {
value = window.btoa(input);
} catch (e) {
const chars = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '='
];
let chr1, chr2, chr3;
let enc1, enc2, enc3, enc4;
let i = 0;
let j = input.length;
while (i < j) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = (chr1 >> 2);
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = (chr3 & 63);
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
value += (chars[enc1] + chars[enc2] + chars[enc3] + chars[enc4]);
}
}
return value;
}
export function noop() {
return true;
}
export function yymmdd(date, separator = '-') {
var d = (date || new Date());
var year = d.getFullYear();
var month = d.getMonth() + 1; // getMonth() 从 0开始
var day = d.getDate();
return `${year}${separator}${padStart(month)}${separator}${padStart(day)}`
}
export function padStart(value, length = 2) {
return String(value).padStart(length, 0);
}
export function normalize() {
return {
milliseconds: (ms % 1000),
seconds: (Math.floor(ms / 1000) % 60),
minutes: (Math.floor(ms / 1000 / 60) % 60),
hours: (Math.floor(ms / 1000 / 60 / 60) % 24),
days: (Math.floor(ms / 1000 / 60 / 60 / 24))
}
}